""" File management models for enhanced file operations """ from sqlalchemy import Column, Integer, String, DateTime, Date, Float, Text, ForeignKey, Boolean from sqlalchemy.orm import relationship from sqlalchemy.sql import func from app.models.base import BaseModel class FileStatusHistory(BaseModel): """ Track file status changes over time Provides audit trail for file status transitions """ __tablename__ = "file_status_history" id = Column(Integer, primary_key=True, autoincrement=True) file_no = Column(String(45), ForeignKey("files.file_no"), nullable=False, index=True) # Status change details old_status = Column(String(45), nullable=False) new_status = Column(String(45), nullable=False) change_date = Column(DateTime(timezone=True), default=func.now(), nullable=False) # Who made the change changed_by_user_id = Column(Integer, ForeignKey("users.id")) changed_by_name = Column(String(100)) # Cached name for reporting # Additional context notes = Column(Text) # Reason for status change system_generated = Column(Boolean, default=False) # True if automated change # Relationships file = relationship("File") changed_by = relationship("User") def __repr__(self): return f" {self.new_status})>" class FileTransferHistory(BaseModel): """ Track file transfers between attorneys Maintains chain of custody for files """ __tablename__ = "file_transfer_history" id = Column(Integer, primary_key=True, autoincrement=True) file_no = Column(String(45), ForeignKey("files.file_no"), nullable=False, index=True) # Transfer details old_attorney_id = Column(String(10), ForeignKey("employees.empl_num"), nullable=False) new_attorney_id = Column(String(10), ForeignKey("employees.empl_num"), nullable=False) transfer_date = Column(DateTime(timezone=True), default=func.now(), nullable=False) # Who authorized the transfer authorized_by_user_id = Column(Integer, ForeignKey("users.id")) authorized_by_name = Column(String(100)) # Transfer context reason = Column(Text) # Reason for transfer effective_date = Column(Date) # When transfer becomes effective (may be future) # Rate changes old_hourly_rate = Column(Float, nullable=True) new_hourly_rate = Column(Float, nullable=True) # Relationships file = relationship("File") old_attorney = relationship("Employee", foreign_keys=[old_attorney_id]) new_attorney = relationship("Employee", foreign_keys=[new_attorney_id]) authorized_by = relationship("User") def __repr__(self): return f" {self.new_attorney_id})>" class FileArchiveInfo(BaseModel): """ Archive information for files Tracks where files are stored and retrieval information """ __tablename__ = "file_archive_info" id = Column(Integer, primary_key=True, autoincrement=True) file_no = Column(String(45), ForeignKey("files.file_no"), nullable=False, unique=True, index=True) # Archive details archive_date = Column(Date, nullable=False, default=func.current_date()) archive_location = Column(String(200)) # Physical or digital location box_number = Column(String(50)) # Physical box identifier shelf_location = Column(String(100)) # Physical shelf/room location # Digital archive info digital_path = Column(String(500)) # Path to digital archive backup_location = Column(String(500)) # Backup storage location # Archive metadata archived_by_user_id = Column(Integer, ForeignKey("users.id")) archived_by_name = Column(String(100)) retrieval_instructions = Column(Text) # How to retrieve the file # Retention information retention_date = Column(Date) # When file can be destroyed destruction_date = Column(Date) # When file was actually destroyed destruction_authorized_by = Column(String(100)) # Archive status is_retrievable = Column(Boolean, default=True) last_verified = Column(Date) # Last time archive was verified to exist # Relationships file = relationship("File") archived_by = relationship("User") def __repr__(self): return f"" class FileClosureChecklist(BaseModel): """ Checklist items for file closure process Ensures all necessary steps are completed before closing """ __tablename__ = "file_closure_checklist" id = Column(Integer, primary_key=True, autoincrement=True) file_no = Column(String(45), ForeignKey("files.file_no"), nullable=False, index=True) # Checklist item details item_name = Column(String(200), nullable=False) item_description = Column(Text) is_required = Column(Boolean, default=True) # Must be completed to close file # Completion tracking is_completed = Column(Boolean, default=False) completed_date = Column(DateTime(timezone=True)) completed_by_user_id = Column(Integer, ForeignKey("users.id")) completed_by_name = Column(String(100)) # Additional info notes = Column(Text) # Notes about completion sort_order = Column(Integer, default=0) # Display order # Relationships file = relationship("File") completed_by = relationship("User") def __repr__(self): status = "✓" if self.is_completed else "○" return f"" class FileAlert(BaseModel): """ Alerts and reminders for files Automated notifications for important dates and events """ __tablename__ = "file_alerts" id = Column(Integer, primary_key=True, autoincrement=True) file_no = Column(String(45), ForeignKey("files.file_no"), nullable=False, index=True) # Alert details alert_type = Column(String(50), nullable=False) # deadline, follow_up, billing, etc. title = Column(String(200), nullable=False) message = Column(Text, nullable=False) # Timing alert_date = Column(Date, nullable=False) # When alert should trigger created_date = Column(Date, default=func.current_date()) # Status is_active = Column(Boolean, default=True) is_acknowledged = Column(Boolean, default=False) acknowledged_by_user_id = Column(Integer, ForeignKey("users.id")) acknowledged_at = Column(DateTime(timezone=True)) # Notification settings notify_attorney = Column(Boolean, default=True) notify_admin = Column(Boolean, default=False) notification_days_advance = Column(Integer, default=7) # Days before alert_date # Relationships file = relationship("File") acknowledged_by = relationship("User") def __repr__(self): status = "🔔" if self.is_active and not self.is_acknowledged else "✓" return f"" class FileRelationship(BaseModel): """ Track relationships between files (e.g., related, parent/child, duplicate). Enables cross-referencing and conflict checks. """ __tablename__ = "file_relationships" id = Column(Integer, primary_key=True, autoincrement=True) source_file_no = Column(String(45), ForeignKey("files.file_no"), nullable=False, index=True) target_file_no = Column(String(45), ForeignKey("files.file_no"), nullable=False, index=True) # Relationship metadata relationship_type = Column(String(45), nullable=False) # related, parent, child, duplicate, conflict, referral notes = Column(Text) # Who created it (cached for reporting) created_by_user_id = Column(Integer, ForeignKey("users.id")) created_by_name = Column(String(100)) # Relationships source_file = relationship("File", foreign_keys=[source_file_no]) target_file = relationship("File", foreign_keys=[target_file_no]) def __repr__(self): return ( f" {self.target_file_no})>" )