progress
This commit is contained in:
191
app/models/file_management.py
Normal file
191
app/models/file_management.py
Normal file
@@ -0,0 +1,191 @@
|
||||
"""
|
||||
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"<FileStatusHistory(file_no='{self.file_no}', {self.old_status} -> {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"<FileTransferHistory(file_no='{self.file_no}', {self.old_attorney_id} -> {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"<FileArchiveInfo(file_no='{self.file_no}', location='{self.archive_location}')>"
|
||||
|
||||
|
||||
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"<FileClosureChecklist({status} {self.item_name} - {self.file_no})>"
|
||||
|
||||
|
||||
|
||||
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"<FileAlert({status} {self.alert_type} - {self.file_no} on {self.alert_date})>"
|
||||
Reference in New Issue
Block a user