aaredb/backend/app/models.py
2024-11-28 10:09:28 +01:00

160 lines
5.9 KiB
Python

from sqlalchemy import Column, Integer, String, Date, ForeignKey, JSON, Interval, DateTime, Boolean
from sqlalchemy.orm import relationship
from app.database import Base
from datetime import datetime, timedelta
import uuid
class Shipment(Base):
__tablename__ = "shipments"
id = Column(Integer, primary_key=True, index=True, autoincrement=True)
shipment_name = Column(String, index=True)
shipment_date = Column(Date)
shipment_status = Column(String)
comments = Column(String(200), nullable=True)
contact_person_id = Column(Integer, ForeignKey("contact_persons.id"))
return_address_id = Column(Integer, ForeignKey("addresses.id"))
proposal_id = Column(Integer, ForeignKey('proposals.id'), nullable=True)
contact_person = relationship("ContactPerson", back_populates="shipments")
return_address = relationship("Address", back_populates="shipments")
proposal = relationship("Proposal", back_populates="shipments")
dewars = relationship("Dewar", back_populates="shipment")
class ContactPerson(Base):
__tablename__ = "contact_persons"
id = Column(Integer, primary_key=True, index=True, autoincrement=True)
firstname = Column(String)
lastname = Column(String)
phone_number = Column(String)
email = Column(String)
shipments = relationship("Shipment", back_populates="contact_person")
class Address(Base):
__tablename__ = "addresses"
id = Column(Integer, primary_key=True, index=True, autoincrement=True)
street = Column(String)
city = Column(String)
zipcode = Column(String)
country = Column(String)
shipments = relationship("Shipment", back_populates="return_address")
class DewarType(Base):
__tablename__ = "dewar_types"
id = Column(Integer, primary_key=True, index=True, autoincrement=True)
dewar_type = Column(String, unique=True, index=True)
serial_numbers = relationship("DewarSerialNumber", back_populates="dewar_type")
class DewarSerialNumber(Base):
__tablename__ = "dewar_serial_numbers"
id = Column(Integer, primary_key=True, index=True, autoincrement=True)
serial_number = Column(String, index=True)
dewar_type_id = Column(Integer, ForeignKey('dewar_types.id'))
dewar_type = relationship("DewarType", back_populates="serial_numbers")
class Dewar(Base):
__tablename__ = "dewars"
id = Column(Integer, primary_key=True, index=True, autoincrement=True)
dewar_name = Column(String)
dewar_type_id = Column(Integer, ForeignKey("dewar_types.id"), nullable=True)
dewar_serial_number_id = Column(Integer, ForeignKey("dewar_serial_numbers.id"), nullable=True)
tracking_number = Column(String)
status = Column(String)
ready_date = Column(Date, nullable=True)
shipping_date = Column(Date, nullable=True)
arrival_date = Column(Date, nullable=True)
returning_date = Column(Date, nullable=True)
unique_id = Column(String, unique=True, index=True, nullable=True)
shipment_id = Column(Integer, ForeignKey("shipments.id"))
return_address_id = Column(Integer, ForeignKey("addresses.id"))
contact_person_id = Column(Integer, ForeignKey("contact_persons.id"))
shipment = relationship("Shipment", back_populates="dewars")
return_address = relationship("Address")
contact_person = relationship("ContactPerson")
pucks = relationship("Puck", back_populates="dewar")
dewar_type = relationship("DewarType")
dewar_serial_number = relationship("DewarSerialNumber")
slot = relationship("Slot", back_populates="dewar")
events = relationship("LogisticsEvent", back_populates="dewar")
beamline_location = None
@property
def number_of_pucks(self) -> int:
return len(self.pucks) if self.pucks else 0
@property
def number_of_samples(self) -> int:
if not self.pucks:
return 0
return sum(len(puck.samples) for puck in self.pucks)
class Proposal(Base):
__tablename__ = "proposals"
id = Column(Integer, primary_key=True, index=True, autoincrement=True)
number = Column(String)
shipments = relationship("Shipment", back_populates="proposal")
class Puck(Base):
__tablename__ = 'pucks'
id = Column(Integer, primary_key=True, index=True, autoincrement=True)
puck_name = Column(String, index=True)
puck_type = Column(String)
puck_location_in_dewar = Column(Integer)
# Foreign keys and relationships
dewar_id = Column(Integer, ForeignKey('dewars.id'))
dewar = relationship("Dewar", back_populates="pucks")
samples = relationship("Sample", back_populates="puck")
class Sample(Base):
__tablename__ = 'samples'
id = Column(Integer, primary_key=True, index=True, autoincrement=True)
sample_name = Column(String, index=True) # Matches `sample_name` in data creation
position = Column(Integer) # Matches `position` in data creation script
data_collection_parameters = Column(JSON, nullable=True)
# Foreign keys and relationships
puck_id = Column(Integer, ForeignKey('pucks.id'))
puck = relationship("Puck", back_populates="samples")
class Slot(Base):
__tablename__ = "slots"
id = Column(String, primary_key=True, index=True)
qr_code = Column(String, unique=True, index=True)
label = Column(String)
qr_base = Column(String, nullable=True)
occupied = Column(Boolean, default=False)
needs_refill = Column(Boolean, default=False)
dewar_unique_id = Column(String, ForeignKey('dewars.unique_id'), nullable=True)
dewar = relationship("Dewar", back_populates="slot")
events = relationship("LogisticsEvent", back_populates="slot")
class LogisticsEvent(Base):
__tablename__ = "logistics_events"
id = Column(Integer, primary_key=True, index=True)
dewar_id = Column(Integer, ForeignKey('dewars.id'))
slot_id = Column(Integer, ForeignKey('slots.id'))
event_type = Column(String, index=True)
timestamp = Column(DateTime, default=datetime.utcnow)
dewar = relationship("Dewar", back_populates="events")
slot = relationship("Slot", back_populates="events")