from sqlalchemy import Column, Integer, String, Float, DateTime, Date, ForeignKey, Boolean, Text from sqlalchemy.sql import func from .database import Base class User(Base): __tablename__ = "users" id = Column(Integer, primary_key=True, index=True) username = Column(String, unique=True, index=True, nullable=False) hashed_password = Column(String, nullable=False) role = Column(String, default="user", nullable=False) # admin, user, readonly created_at = Column(DateTime(timezone=True), server_default=func.now()) class Drug(Base): __tablename__ = "drugs" id = Column(Integer, primary_key=True, index=True) name = Column(String, unique=True, index=True, nullable=False) description = Column(String, nullable=True) is_controlled = Column(Boolean, nullable=False, default=False) created_at = Column(DateTime(timezone=True), server_default=func.now()) updated_at = Column(DateTime(timezone=True), onupdate=func.now(), server_default=func.now()) class DrugVariant(Base): __tablename__ = "drug_variants" id = Column(Integer, primary_key=True, index=True) drug_id = Column(Integer, ForeignKey("drugs.id"), nullable=False) strength = Column(String, nullable=False) # e.g., "5.4mg", "16mg", "100ml" quantity = Column(Float, nullable=False, default=0) unit = Column(String, nullable=False, default="units") # tablets, bottles, ml, etc low_stock_threshold = Column(Float, nullable=False, default=10) created_at = Column(DateTime(timezone=True), server_default=func.now()) updated_at = Column(DateTime(timezone=True), onupdate=func.now(), server_default=func.now()) class Dispensing(Base): __tablename__ = "dispensings" id = Column(Integer, primary_key=True, index=True) drug_variant_id = Column(Integer, ForeignKey("drug_variants.id"), nullable=False) batch_id = Column(Integer, ForeignKey("batches.id"), nullable=True) actor_user_id = Column(Integer, ForeignKey("users.id"), nullable=True) quantity = Column(Float, nullable=False) animal_name = Column(String, nullable=True) # Name/ID of the animal (optional) user_name = Column(String, nullable=False) # User who dispensed dispensed_at = Column(DateTime(timezone=True), server_default=func.now(), index=True) notes = Column(String, nullable=True) class Location(Base): __tablename__ = "locations" id = Column(Integer, primary_key=True, index=True) name = Column(String, unique=True, index=True, nullable=False) is_active = Column(Boolean, nullable=False, default=True) created_at = Column(DateTime(timezone=True), server_default=func.now()) updated_at = Column(DateTime(timezone=True), onupdate=func.now(), server_default=func.now()) class Batch(Base): __tablename__ = "batches" id = Column(Integer, primary_key=True, index=True) drug_variant_id = Column(Integer, ForeignKey("drug_variants.id"), nullable=False, index=True) batch_number = Column(String, nullable=False, index=True) quantity = Column(Float, nullable=False, default=0) expiry_date = Column(Date, nullable=False, index=True) location_id = Column(Integer, ForeignKey("locations.id"), nullable=False, index=True) received_at = Column(DateTime(timezone=True), nullable=False, server_default=func.now(), index=True) notes = Column(String, nullable=True) created_at = Column(DateTime(timezone=True), server_default=func.now()) updated_at = Column(DateTime(timezone=True), onupdate=func.now(), server_default=func.now()) class DispensingAllocation(Base): __tablename__ = "dispensing_allocations" id = Column(Integer, primary_key=True, index=True) dispensing_id = Column(Integer, ForeignKey("dispensings.id"), nullable=False, index=True) batch_id = Column(Integer, ForeignKey("batches.id"), nullable=False, index=True) quantity = Column(Float, nullable=False) class AuditLog(Base): __tablename__ = "audit_logs" id = Column(Integer, primary_key=True, index=True) action = Column(String, nullable=False, index=True) entity_type = Column(String, nullable=False, index=True) entity_id = Column(Integer, nullable=True, index=True) actor_user_id = Column(Integer, ForeignKey("users.id"), nullable=True, index=True) actor_username = Column(String, nullable=False, index=True) details = Column(Text, nullable=True) created_at = Column(DateTime(timezone=True), server_default=func.now(), index=True)