Exemplo n.º 1
0
class Restaurant(SearchableMixin, db.Model):
    __tablename__ = "restaurant"
    __searchable__ = ["name", "phone", "average_rating"]

    id = db.Column(db.Integer, primary_key=True, autoincrement=True)

    name = db.Column(db.Text(100))

    lat = db.Column(db.Float)  # restaurant latitude
    lon = db.Column(db.Float)  # restaurant longitude

    phone = db.Column(db.Unicode(40))
    time_of_stay = db.Column(db.Integer)  # minutes
    cuisine_type = db.Column(db.Enum(CuisineType))
    opening_hours = db.Column(db.Integer)
    closing_hours = db.Column(db.Integer)
    operator_id = db.Column(db.Integer, db.ForeignKey("operator.id"))
    average_rating = db.Column(db.Integer, default=0)

    # precautions = db.relationship("Precaution", secondary=precautions, backref="restaurants")
    tables = db.relationship("Table", back_populates="restaurant")
    reviews = db.relationship("Review", back_populates="restaurant")
    menus = db.relationship("Menu", back_populates="restaurant")

    def get_bookings(self, starting_booking_datetime: datetime):
        """Get all the bookings that were confirmed starting from a specific time.

        Args:
            starting_booking_time (datetime): the starting time of the booking
        """
        total_real_bookings = []
        for table in self.tables:
            bookings = [
                b for b in table.booking
                if b.checkin and b.start_booking == starting_booking_datetime
            ]
            total_real_bookings.extend(bookings)

        return total_real_bookings

    def get_free_table(self, seats, date_hour):
        filtered_tables = []
        tables_list = Table.query.filter_by(restaurant_id=self.id).order_by(
            Table.seats.asc())
        for table in tables_list:
            if table.seats >= seats:
                filtered_tables.append(table)

        id_booked_tables = []
        for table in filtered_tables:
            for booking in table.booking:
                if booking.start_booking == date_hour:
                    id_booked_tables.append(table.id)
                    break

        for table in filtered_tables:
            if table.id not in id_booked_tables:
                return table.id
        return None
Exemplo n.º 2
0
class Menu(db.Model):
    __tablename__ = "menu"
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)

    name = db.Column(db.Text(100))
    restaurant_id = db.Column(db.Integer, db.ForeignKey("restaurant.id"))

    restaurant = db.relationship("Restaurant", back_populates="menus")
    foods = db.relationship("Food", secondary=MenuItems, back_populates="menu")
Exemplo n.º 3
0
class Table(db.Model):
    __tablename__ = "table"
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)

    name = db.Column(db.Text(100))
    seats = db.Column(db.Integer)

    restaurant_id = db.Column(db.Integer, db.ForeignKey("restaurant.id"))

    restaurant = db.relationship("Restaurant", back_populates="tables")
    booking = db.relationship("Booking", back_populates="table")
Exemplo n.º 4
0
class Mark(TimestampMixin, db.Model):
    __tablename__ = "mark"
    user_id = db.Column(db.Integer, db.ForeignKey("user.id"), primary_key=True)
    authority_id = db.Column(db.Integer,
                             db.ForeignKey("authority.id"),
                             primary_key=True)

    authority = db.relationship("HealthAuthority", back_populates="marks")
    user = db.relationship("User", back_populates="marks")

    duration = db.Column(db.Integer, default=14)
Exemplo n.º 5
0
class Review(TimestampMixin, db.Model):
    __tablename__ = "review"
    user_id = db.Column(db.Integer, db.ForeignKey("user.id"), primary_key=True)
    restaurant_id = db.Column(db.Integer,
                              db.ForeignKey("restaurant.id"),
                              primary_key=True)

    restaurant = db.relationship("Restaurant", back_populates="reviews")
    user = db.relationship("User", back_populates="reviews")

    rating = db.Column(db.SmallInteger, nullable=False)
    message = db.Column(db.UnicodeText)
Exemplo n.º 6
0
class HealthAuthority(AbstractUser):
    __tablename__ = "authority"
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    email = db.Column(db.Unicode(128))
    name = db.Column(db.Unicode(128))
    password_hash = db.Column(db.Unicode(128))
    phone = db.Column(db.Unicode(40))

    country = db.Column(db.Unicode(128))
    state = db.Column(db.Unicode(128))
    city = db.Column(db.Unicode(128))
    lat = db.Column(db.Float)
    lon = db.Column(db.Float)

    marks = db.relationship("Mark", back_populates="authority")

    def __init__(self, *args, **kw):
        super().__init__(*args, **kw)

    def mark(self, user: User, duration=14, starting_date=datetime.utcnow()):
        logger.info(
            f"Authority (id={self.id}, name={self.name}) just marked the user (ID={user.id}, firstname={user.firstname})"
        )
        self.marks.append(
            Mark(user=user,
                 authority=self,
                 duration=duration,
                 created=starting_date))
Exemplo n.º 7
0
class Food(db.Model):
    __tablename__ = "food"
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)

    category = db.Column(db.Enum(FoodCategory))
    name = db.Column(db.Text(100))
    price = db.Column(db.Float)

    menu = db.relationship("Menu", secondary=MenuItems, back_populates="foods")
Exemplo n.º 8
0
class Operator(AbstractUser):
    __tablename__ = "operator"
    restaurants = db.relationship("Restaurant", backref="operator")

    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    email = db.Column(db.Unicode(128), nullable=False)
    firstname = db.Column(db.Unicode(128))
    lastname = db.Column(db.Unicode(128))
    password_hash = db.Column(db.Unicode(128))
    dateofbirth = db.Column(db.DateTime)
    phone_number = db.Column(db.Unicode(40))
    fiscal_code = db.Column(db.Unicode(128))

    def __init__(self, *args, **kw):
        super().__init__(*args, **kw)
Exemplo n.º 9
0
class User(AbstractUser):
    __tablename__ = "user"
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    avatar_id = db.Column(db.Unicode(128))
    fiscal_code = db.Column(db.Unicode(128))
    email = db.Column(db.Unicode(128))
    phone_number = db.Column(db.Unicode(40))
    firstname = db.Column(db.Unicode(128), nullable=False)
    lastname = db.Column(db.Unicode(128))
    password_hash = db.Column(db.Unicode(128))
    dateofbirth = db.Column(db.DateTime)

    marks = db.relationship("Mark", back_populates="user")
    reviews = db.relationship("Review", back_populates="user")

    booking = db.relationship("Booking", back_populates="user")

    def __init__(self, *args, **kw):
        super().__init__(*args, **kw)

        from hashlib import sha1
        from base64 import b32encode

        hashed = sha1((datetime.utcnow().isoformat() + self.firstname).encode("utf-8"))
        self.avatar_id = b32encode(hashed.digest()).decode("utf-8")

    def review(self, restaurant: Restaurant, rating: int, message=""):
        """Add a review, formed by a rating and a message, to a specific restaurant

        Args:
            restaurant (Restaurant): the restaurant to which add the review
            rating (int): the rating
            message (str): the review itself
        """
        self.reviews.append(
            Review(user=self, restaurant=restaurant, rating=rating, message=message)
        )

    def already_reviewed(self, restaurant: Restaurant):
        return sum(1 for r in self.reviews if r.restaurant_id == restaurant.id) != 0

    def has_been_marked(self) -> bool:
        """Returns weather the user has been marked in the past or is currently marked.

        Returns:
            bool: boolean value
        """
        if self.marks:
            return True
        else:
            False

    def is_marked(self) -> bool:
        """Returns weather the user is currently marked.

        Returns:
            bool: boolean value
        """
        return self.has_been_marked() and self.get_remaining_mark_days() > 0

    def get_last_mark(self) -> Mark:
        """
        Returns the last mark that has been done.
        The supposition, is that the last one made, is more accurate.
        Thus if the previous one lasts longer than the new one, the new one is still accepted.

        Returns:
            Mark: the last one that has been done.
        """
        return max(self.marks, key=lambda mark: mark.created)

    def get_last_mark_duration(self):
        return self.get_last_mark().duration

    def get_mark_expiration_date(self, from_date=datetime.utcnow()) -> datetime:
        last_mark = self.get_last_mark()
        return last_mark.created + timedelta(days=last_mark.duration + 1)

    def get_remaining_mark_days(self, from_date=datetime.utcnow()):
        return (self.get_mark_expiration_date() - from_date).days - 1

    def has_been_deleted(self) -> bool:
        """Returns weather the user has unsubscribed

        Returns:
            bool: boolean value
        """
        return self.email == "*****@*****.**"

    def get_bookings(self, from_date=datetime.utcnow(), range_duration=14):
        """
            It returns a list of bookings that the user made in a range from a starting date.
        Args:
            from_date (datetime, optional): is the date from which to start searching. Defaults to datetime.utcnow().
            range_duration (int, optional): it's the range of days. Defaults to 14.

        Returns:
            [type]: [description]
        """
        return [
            b
            for b in self.booking
            if b.start_booking >= (from_date - timedelta(days=range_duration))
        ]

    def check_equality_for_booking(self, firstname, lastname, email):
        return (
            self.firstname == firstname
            and self.lastname == lastname
            and self.email == email
        )

    def get_avatar_link(self):
        from flask import current_app

        return current_app.config["AVATAR_PROVIDER"].format(seed=self.avatar_id)