class Rule(db.Model): __tablename__ = 'rule' __table_args = (db.UniqueConstraint('text', 'condominium_id'), db.Index('rule_idx', 'text')) id = db.Column(db.Integer, primary_key=True) text = db.Column(db.String(500), nullable=False) employee_id = db.Column(db.Integer, db.ForeignKey('employee.id', ondelete='CASCADE'), nullable=False) condominium_id = db.Column(db.Integer, db.ForeignKey('condominium.id', ondelete='CASCADE'), nullable=False) author = db.relationship('Employee', backref=db.backref('rules', lazy=True, cascade='all, delete'), lazy=False) condominium = db.relationship( 'Condominium', backref=db.backref('rules', lazy=True, cascade='all, delete'), lazy=True, primaryjoin= 'and_(Rule.condominium_id == Condominium.id, Condominium.active == 1)') def __repr__(self): return f'Rule(text={self.text})'
class Show(db.Model): __tablename__ = 'show' id = db.Column(db.Integer, primary_key=True) start_time = db.Column(db.DateTime()) artist_id = db.Column(db.Integer, db.ForeignKey('artist.id'), nullable=False) venue_id = db.Column(db.Integer, db.ForeignKey('venue.id'), nullable=False) def __repr__(self): return f'<Show of the Artist that his ID: { self.artist_id } , and the venue ID: { self.venue_id }>'
class Movie(db.Model): __tablename__ = 'movie' id = db.Column(db.Integer, primary_key=True) title = db.Column(db.String(50), nullable=False) date_posted = db.Column(db.DateTime, nullable=False, default=datetime.datetime.now) release_year = db.Column(db.Integer, nullable=False) director = db.Column(db.String(30), nullable=False) duration_hrs = db.Column(db.Integer, nullable=False) duration_mins = db.Column(db.Integer, nullable=False) rate = db.Column(db.Integer, nullable=False) storyline = db.Column(db.String(1000), nullable=False) poster = db.Column(db.String(1000), nullable=False, default='movie_poster_default.jpg') genre_id = db.Column(db.Integer, db.ForeignKey('genre.id'), nullable=False) genre = db.relationship('Genre') user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False) user = db.relationship('User') def __repr__(self): return ("Movie" f"('{self.title}'," f" '{self.director}'," f" '{self.rate}'," f" '{self.duration_hrs}:{self.duration_mins}'," f" '{self.release_year}'," f" '{self.genre.name}'" f" '{self.author.username}'" f" '{self.date_posted.strftime('%Y-%m-%d %I:%M%p')}')") @property def serialize(self): return { 'id': self.id, 'title': self.title, 'date_posted': self.date_posted, 'release_year': self.release_year, 'director': self.director, 'duration_hrs': self.duration_hrs, 'duration_mins': self.duration_mins, 'rate': self.rate, 'poster': self.poster, 'genre': self.genre.name, 'genre_id': self.genre_id, 'user': self.user.username, 'user_id': self.user_id, 'poster': self.poster }
class Flight(TimestampMixin, PersistableMixin, db.Model): id = db.Column(db.Integer, primary_key=True) destination_id = db.Column(db.Integer, db.ForeignKey('destination.id')) destination = relationship("Destination", back_populates="flights") beginning = db.Column(db.Date, nullable=False) end = db.Column(db.Date, nullable=False) cost = db.Column(db.Float, nullable=False) url = db.Column(db.String(200), nullable=False) def __repr__(self): return f"<Flight id='{self.id}' cost='{self.cost}'" def to_csv(self): return ", ".join([ str(self.id), self.created.strftime('%e %b %Y %H:%M:%S%p'), self.beginning.strftime('%e %b %Y'), self.end.strftime('%e %b %Y'), str(self.cost), self.url ]) @property def dates(self): return f"{self.beginning.strftime('%b %d')} - {self.end.strftime('%b %d')}" def num_days(self): return (self.end - self.beginning).days def month(self): return self.beginning.strftime("%B") def chart_timestamp(self): return self.created.strftime("%Y-%m-%d %H:%M:%S ") + "-0800"
class Resident(db.Model): __tablename__ = 'resident' __table_args__ = (db.UniqueConstraint('cpf', 'apartment_id'), db.Index('resident_idx', 'cpf', 'apartment_id')) id = db.Column(db.Integer, primary_key=True) cpf = db.Column(db.String(11), nullable=False) name = db.Column(db.String(50), nullable=False) birthday = db.Column(db.Date, nullable=False) photo_location = db.Column(db.String(200), nullable=True, default='data/photos/default/resident.png') apartment_id = db.Column(db.Integer, db.ForeignKey('apartment.id', ondelete='CASCADE'), nullable=False) apartment = db.relationship( 'Apartment', backref=db.backref('residents', lazy=True, cascade='all, delete'), lazy=True, primaryjoin= 'and_(Resident.apartment_id == Apartment.id, Apartment.active == 1)') def __repr__(self): return f'Resident(id={self.id}, ' \ f'name={self.name}, ' \ f'birthday={self.birthday})'
class Guest(db.Model): __tablename__ = 'guest' __table_args__ = (db.UniqueConstraint('name', 'arrival', 'apartment_id'), db.Index('guest_idx', 'name', 'arrival', 'apartment_id')) id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(50), nullable=False) arrival = db.Column(db.DateTime, nullable=False) active = db.Column(db.SmallInteger, default=1) apartment_id = db.Column(db.Integer, db.ForeignKey('apartment.id', ondelete='CASCADE'), nullable=False) apartment = db.relationship( 'Apartment', backref=db.backref( 'guests', lazy=True, cascade='all, delete', primaryjoin= 'and_(Guest.apartment_id == Apartment.id, Guest.active == 1)'), lazy=True, primaryjoin= 'and_(Guest.apartment_id == Apartment.id, Apartment.active == 1)') def __repr__(self): return f'Guest(id={self.id}, name={self.name}, arrival={self.arrival})'
class Employee(db.Model): __tablename__ = 'employee' __table_args__ = ( db.UniqueConstraint('cpf', 'role', 'condominium_id'), db.Index('employee_idx', 'cpf', 'role', 'condominium_id') ) id = db.Column(db.Integer, primary_key=True) cpf = db.Column(db.String(11), nullable=False) name = db.Column(db.String(50), nullable=False) birthday = db.Column(db.Date, nullable=False) photo_location = db.Column(db.String(200), nullable=True, default='data/photos/default/employee.png') role = db.Column(db.String(50), nullable=False) type = db.Column(db.SmallInteger, nullable=False) condominium_id = db.Column(db.Integer, db.ForeignKey('condominium.id', ondelete='CASCADE'), nullable=False) active = db.Column(db.SmallInteger, default=1) condominium = db.relationship('Condominium', backref=db.backref('employees', lazy=True, cascade='all, delete'), lazy=True, primaryjoin='and_(Employee.condominium_id == Condominium.id, Condominium.active == 1)') def __repr__(self): return f'Employee(id={self.id}, ' \ f'cpf={self.cpf}, ' \ f'name={self.name}, ' \ f'birthday={self.birthday}, ' \ f'role={self.role})'
class Employee(db.Model): __tablename__ = 'employee' __table_args__ = {'mysql_engine': 'InnoDB'} id = db.Column(db.Integer, primary_key=True) first_name = db.Column(db.String(64), nullable=False) last_name = db.Column(db.String(64), nullable=False) salary = db.Column(db.Integer, nullable=True) department = db.Column(db.String(64), db.ForeignKey('department.name', ondelete='SET NULL', onupdate='CASCADE'), nullable=True) birth_date = db.Column(db.Date, nullable=False) hire_date = db.Column(db.Date, nullable=False, default=date.today()) dept = db.relationship('Department', backref=db.backref('employee', passive_deletes=True, passive_updates=True)) head = db.relationship('Head', backref='employee', passive_deletes=True, uselist=False) def serialize(self): return { 'id': self.id, 'first_name': self.first_name, 'last_name': self.last_name, 'salary': self.salary, 'department': self.department, 'birth_date': dump_date(self.birth_date), 'hire_date': dump_date(self.hire_date) }
class Note(db.Model): __tablename__ = 'note' note_id = db.Column(db.Integer, primary_key=True) c_id = db.Column(db.Integer, db.ForeignKey('company.c_id')) content = db.Column(db.String, nullable=False) timestamp = db.Column(db.DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
class Event(db.Model): __tablename__ = 'event' __table_args__ = (db.UniqueConstraint('event_type_id', 'start_datetime', 'end_datetime'), db.Index('event_idx', 'start_datetime', 'end_datetime')) id = db.Column(db.Integer, primary_key=True) start_datetime = db.Column(db.DateTime, nullable=False) end_datetime = db.Column(db.DateTime, nullable=False) active = db.Column(db.SmallInteger, default=1) event_type_id = db.Column(db.Integer, db.ForeignKey('event_type.id', ondelete='CASCADE'), nullable=False) apartment_id = db.Column(db.Integer, db.ForeignKey('apartment.id', ondelete='CASCADE'), nullable=False) apartment = db.relationship( 'Apartment', backref=db.backref( 'events', lazy=True, cascade='all, delete', primaryjoin= 'and_(Event.apartment_id == Apartment.id, Event.active == 1)'), lazy=True, primaryjoin= 'and_(Event.apartment_id == Apartment.id, Apartment.active == 1)') event_type = db.relationship( 'EventType', backref=db.backref( 'events', lazy=True, cascade='all, delete', primaryjoin= 'and_(Event.event_type_id == EventType.id, Event.active == 1)'), lazy=False) def __repr__(self): return f'Event(id={self.id}, ' \ f'start_datetime={self.start_datetime}, ' \ f'end_datetime={self.end_datetime})'
class Head(db.Model): __tablename__ = 'head' __table_args__ = {'mysql_engine': 'InnoDB'} department_name = db.Column(db.String(64), db.ForeignKey('department.name', ondelete='CASCADE', onupdate='CASCADE'), primary_key=True) head_id = db.Column(db.Integer, db.ForeignKey('employee.id', ondelete='SET NULL', onupdate='CASCADE'), nullable=True) def serialize(self): return { 'department_name': self.department_name, 'head_id': self.head_id, }
class Employee(db.Model): id = db.Column(db.Integer(), primary_key=True) department_id = db.Column(db.Integer, db.ForeignKey('department.id')) name = db.Column(db.Integer()) date_of_birth = db.Column(db.Date, nullable=False) salary = db.Column(db.Integer()) def __repr__(self): return str(self.id) + ' ' + self.name + ' ' + str( self.date_of_birth) + ' ' + str(self.salary) + ' ' + str( self.department_id)
class Notification(db.Model): __tablename__ = 'notification' __table_args__ = ( db.UniqueConstraint('title', 'condominium_id'), db.Index('date_idx', 'finish_date'), db.Index('notification_idx', 'title', 'condominium_id') ) id = db.Column(db.Integer, primary_key=True) type = db.Column(db.Integer, nullable=False) title = db.Column(db.String(50), nullable=False) text = db.Column(db.String(300), nullable=False) finish_date = db.Column(db.Date, nullable=True) active = db.Column(db.SmallInteger, default=1) employee_id = db.Column(db.Integer, db.ForeignKey('employee.id', ondelete='CASCADE'), nullable=False) condominium_id = db.Column(db.Integer, db.ForeignKey('condominium.id', ondelete='CASCADE'), nullable=False) author = db.relationship('Employee', backref=db.backref('notifications', lazy=True, cascade='all, delete', primaryjoin='and_(Notification.employee_id == Employee.id, Notification.active == 1)'), lazy=True) condominium = db.relationship('Condominium', backref=db.backref('notifications', lazy=True, cascade='all, delete', primaryjoin='and_(Notification.condominium_id == Condominium.id, Notification.active == 1)'), lazy=True, primaryjoin='and_(Notification.condominium_id == Condominium.id, Condominium.active == 1)') def __repr__(self): return f'Notification(id={self.id}, ' \ f'type={self.type}, ' \ f'title={self.title}, ' \ f'text={self.text}, ' \ f'finish_date={self.finish_date})'
class Record(db.Model): id = db.Column(db.Integer, primary_key=True) datetime = db.Column(db.DateTime, default=datetime.now, nullable=False) # time = db.Column(db.Text, nullable=True) text = db.Column(db.String(250), nullable=False) num_calories = db.Column(db.Integer, nullable=False) user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False) # In user model, Test is started with capital letter because we are using the actual Test class. # But here we use 'user.id' with small u because it is actual table in db, and actual column # table and column name are simply lowercase by default def __repr__(self): return f"Record('{self.id}, {self.datetime}, {self.text}, {self.num_calories}, {self.user_id}')"
class ResidentUser(db.Model): __tablename__ = 'resident_user' __table_args__ = (db.UniqueConstraint('apartment_id'), db.UniqueConstraint('username')) id = db.Column(db.Integer, primary_key=True) username = db.Column(db.String(100), db.ForeignKey('username.username', ondelete='CASCADE'), nullable=False) password = db.Column(db.String(200), nullable=False) apartment_id = db.Column(db.Integer, db.ForeignKey('apartment.id', ondelete='CASCADE'), nullable=False) apartment = db.relationship( 'Apartment', backref=db.backref('user', lazy=True, cascade='all, delete', uselist=False), lazy=True, uselist=False, primaryjoin= 'and_(ResidentUser.apartment_id == Apartment.id, Apartment.active == 1)' ) _username = db.relationship('Username', backref=db.backref('resident_user', lazy=True, cascade='all, delete', uselist=False), lazy=True, uselist=False) def __repr__(self): return f'ResidentUser(username={self.username})'
class Actual(db.Model): #__tablename__ = 'actuals' id = db.Column(db.Integer, primary_key=True) temp = db.Column(db.Integer) rain = db.Column(db.Integer) date = db.Column(db.Date) crag_id = db.Column(db.Integer, db.ForeignKey('crag.id')) crag = db.relationship("Crag", backref=db.backref("actuals", lazy='dynamic')) def __repr__(self): return "<Actual(crag=%s, temp=%d, rain=%s, date=%s>" % ( self.crag_id, self.temp, self.rain, self.date.strftime("%b %d %y"))
class Address(db.Model): __tablename__ = 'address' __table_args__ = (db.UniqueConstraint('street_name', 'city_id'), db.Index('address_idx', 'street_name', 'city_id')) id = db.Column(db.Integer, primary_key=True) street_name = db.Column(db.String(150), nullable=False) neighbourhood = db.Column(db.String(150), nullable=False) city_id = db.Column(db.Integer, db.ForeignKey('city.id', ondelete='CASCADE'), nullable=False) city = db.relationship('City', backref=db.backref('addresses', lazy=True, cascade='all, delete'), lazy=False) def __repr__(self): return f'Address(id={self.id}, ' \ f'street_name={self.street_name}, ' \ f'neighbourhood={self.neighbourhood}, ' \ f'city_name={self.city.name})'
class Tower(db.Model): __tablename__ = 'tower' __table_args__ = (db.UniqueConstraint('name', 'condominium_id'), db.Index('tower_idx', 'name', 'condominium_id')) id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(10), nullable=False) condominium_id = db.Column(db.Integer, db.ForeignKey('condominium.id', ondelete='CASCADE'), nullable=False) active = db.Column(db.SmallInteger, default=1) condominium = db.relationship('Condominium', backref=db.backref('towers', lazy=True, cascade='all, delete'), lazy=True, primaryjoin='and_(Tower.condominium_id == Condominium.id, Condominium.active == 1)') def __repr__(self): return f'Tower(id={self.id}, ' \ f'tower_name={self.name})'
class Forecast(db.Model): #__tablename__ = 'forecasts' id = db.Column(db.Integer, primary_key=True) service = db.Column(db.String, nullable=False) crag_id = db.Column(db.Integer, db.ForeignKey('crag.id')) temp = db.Column(db.Integer) rain = db.Column(db.Integer) pred_time = db.Column(db.DateTime) pred_for = db.Column(db.Date) crag = db.relationship("Crag", backref=db.backref("forecasts", lazy='dynamic')) def __repr__(self): return "<Forecast(service=%s, crag=%s, temp=%d, rain=%d, pred_time=%s, pred_for=%s)>" % ( self.service, self.crag_id, self.temp, self.rain, self.pred_time.strftime("%b %d %y, %H:%M"), self.pred_for.strftime("%b %d %y"))
class ProductBatch(db.Model): __tablename__ = 'ProductBatch' batchID = db.Column(db.Integer, primary_key=True) SKU = db.Column(db.Integer, db.ForeignKey('Product.SKU'), nullable=False) producer = db.Column(db.String(24), nullable=False) batch_quantity = db.Column(db.Integer, nullable=False) batch_expiration = db.Column(db.DateTime, nullable=False) def __init__(self, SKU, producer, batch_quantity, batch_expiration): self.SKU = SKU self.batch_quantity = batch_quantity self.producer = producer # datetime.datetime(year, month, day) self.batch_expiration = batch_expiration def __repr__(self): return '<ProductBatch {}, {}>'.format(self.batchID, self.SKU)
class State(db.Model): __tablename__ = 'state' __table_args__ = (db.UniqueConstraint('name', 'country_id'), db.Index('state_idx', 'name', 'country_id')) id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(60), nullable=False) country_id = db.Column(db.Integer, db.ForeignKey('country.id', ondelete='CASCADE'), nullable=False) country = db.relationship('Country', backref=db.backref('states', lazy=True, cascade='all, delete'), lazy=True) def __repr__(self): return f'State(id={self.id}, name={self.name})'
class Apartment(db.Model): __tablename__ = 'apartment' __table_args__ = (db.UniqueConstraint('apt_number', 'tower_id'), db.Index('apt_idx', 'apt_number', 'tower_id')) id = db.Column(db.Integer, primary_key=True) apt_number = db.Column(db.Integer, nullable=False) tower_id = db.Column(db.Integer, db.ForeignKey('tower.id', ondelete='CASCADE'), nullable=False) active = db.Column(db.SmallInteger, default=1) tower = db.relationship( 'Tower', backref=db.backref('apartments', lazy=True, cascade='all, delete'), lazy=True, primaryjoin='and_(Apartment.tower_id == Tower.id, Tower.active == 1)') def __repr__(self): return f'Apartment(id={self.id},' \ f'apt_number={self.apt_number})'
class EventType(db.Model): __tablename__ = 'event_type' __table_args__ = (db.UniqueConstraint('name', 'condominium_id'), ) id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(30), nullable=False, index=True) condominium_id = db.Column(db.Integer, db.ForeignKey('condominium.id', ondelete='CASCADE'), nullable=False) condominium = db.relationship( 'Condominium', backref=db.backref('event_types', lazy=True, cascade='all, delete'), lazy=True, primaryjoin= 'and_(EventType.condominium_id == Condominium.id, Condominium.active == 1)' ) def __repr__(self): return f'EventType(id={self.id}, name={self.name})'
class Condominium(db.Model): __tablename__ = 'condominium' __table_args__ = (db.UniqueConstraint('street_number', 'address_id'), db.Index('cond_idx', 'street_number', 'address_id')) id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(60), nullable=False) street_number = db.Column(db.Integer, nullable=False) photo_location = db.Column(db.String(200), nullable=True, default='data/photos/default/condominium.png') address_id = db.Column(db.Integer, db.ForeignKey('address.id', ondelete='CASCADE'), nullable=False) active = db.Column(db.SmallInteger, default=1) address = db.relationship('Address', backref=db.backref('condominiums', lazy=True, cascade='all, delete', primaryjoin='and_(Address.id == Condominium.address_id, Condominium.active == 1)'), lazy=True, primaryjoin='and_(Condominium.address_id == Address.id, Condominium.active == 1)') def __repr__(self): return f'Condominium(id={self.id}, ' \ f'condominium_name={self.name})'
class Address(db.Model): __tablename__ = 'Address' addressID = db.Column(db.Integer, primary_key=True) customerID = db.Column(db.Integer, db.ForeignKey('Customer.customerID'), nullable=False) line1 = db.Column(db.String(100), nullable=False) line2 = db.Column(db.String(100)) city = db.Column(db.String(32), nullable=False) state = db.Column(db.String(10), nullable=False) zipCode = db.Column(db.String(10), nullable=False) country = db.Column(db.String(20), nullable=False) def __init__(self, customerID, line1, city, state, zipCode, country): self.customerID = customerID self.line1 = line1 self.city = city self.state = state self.zipCode = zipCode self.country = country def __repr__(self): return '<Address: {}, customer: {}>'.format(self.addressID, self.customerID)
class Reservation(db.Model): id = db.Column(db.Integer, primary_key=True) user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False) room_id = db.Column(db.Integer, db.ForeignKey('room.id'), nullable=False) start = db.Column(db.DateTime, nullable=False) end = db.Column(db.DateTime, nullable=False) cancelled = db.Column(db.Boolean, default=False, nullable=False) def duration(self): return self.end - self.start def __repr__(self): return '<Reservation: %s by %s from %s-%s>' % (self.room, self.user, self.start, self.end) @staticmethod def contiguous_before(reservations, start): reservation_before = reservations.filter( Reservation.end == start).first() if reservation_before: return [reservation_before] + Reservation.contiguous_before( reservations, reservation_before.start) return [] @staticmethod def contiguous_after(reservations, end): reservation_after = reservations.filter( Reservation.start == end).first() if reservation_after: return [reservation_after] + Reservation.contiguous_after( reservations, reservation_after.end) return [] @validates('user_id', 'room_id', 'start', 'end') def validates_times(self, key, value): if key == 'end': start, end = self.start, value now = datetime.datetime.now() duration = end - start week_start = start.date() - datetime.timedelta( days=start.weekday()) week_end = week_start + datetime.timedelta(days=7) day_start = start.date() day_end = day_start + datetime.timedelta(days=1) admin = self.user_id in admins room = db_session.query(Room).filter_by( id=int(self.room_id)).first() config = functools.partial(app.config['config'].getint, 'SCHEDULING') user_reservations = room.reservations.filter( (Reservation.id != self.id) & (Reservation.cancelled == False) & # noqa: E712 (SQLAlchemy requires it) (Reservation.user_id == self.user_id)) contiguous_reservations = Reservation.contiguous_before( user_reservations, start) + Reservation.contiguous_after( user_reservations, end) contiguous_duration = sum( map(operator.methodcaller('duration'), contiguous_reservations), datetime.timedelta()) week_reservations = user_reservations.filter( (Reservation.start >= week_start) & (Reservation.start <= week_end)).all() week_reservation_duration = sum( map(operator.methodcaller('duration'), week_reservations), datetime.timedelta()) day_reservations = user_reservations.filter( (Reservation.start >= day_start) & (Reservation.start <= day_end)).all() day_reservation_duration = sum( map(operator.methodcaller('duration'), day_reservations), datetime.timedelta()) assert start > now, \ 'Reservation must start in the future' assert (start - now) <= datetime.timedelta(days=config('MAX_DAYS_IN_FUTURE')), \ 'Reservation must start in the next %d days' % config('MAX_DAYS_IN_FUTURE') assert end > start, \ 'Reservation must end after it starts' assert admin or datetime.timedelta(minutes=config('MINIMUM_DURATION_MINUTES')) <= duration, \ 'Reservation must be at least %d minutes' % config('MINIMUM_DURATION_MINUTES') assert admin or duration <= datetime.timedelta(hours=config('MAX_CONTIGUOUS_DURATION_HOURS')), \ 'Reservation must not be longer than %d hours' % config('MAX_CONTIGUOUS_DURATION_HOURS') assert admin or duration + contiguous_duration <= datetime.timedelta(hours=config('MAX_CONTIGUOUS_DURATION_HOURS')), \ 'Reservations must not be longer than %d contiguous hours' % config('MAX_CONTIGUOUS_DURATION_HOURS') assert room.reservations.filter(Reservation.cancelled == False, Reservation.id != self.id).filter( # noqa: E712 (SQLAlchemy requires it) ((Reservation.start <= start) & (Reservation.end > start)) | ((Reservation.start >= start) & (Reservation.end <= end)) | ((Reservation.start < end) & (Reservation.end >= end)) ).count() == 0, \ 'Reservation must not overlap with another' assert admin or duration + week_reservation_duration <= datetime.timedelta(hours=config('MAX_WEEK_HOURS')), \ 'Reservations must not exceed %d hours per week' % config('MAX_WEEK_HOURS') assert admin or duration + day_reservation_duration <= datetime.timedelta(hours=config('MAX_DAY_HOURS')), \ 'Reservations must not exceed %d hours per day' % config('MAX_DAY_HOURS') assert len(day_reservations) + 1 <= config('MAX_DAY_RESERVATIONS'), \ 'Reservations per day may not exceed %d reservations' % config('MAX_DAY_RESERVATIONS') return value