def initialize_extensions(app): """Initialize extensions for the app""" DB.init_app(app) import timeless.customers.models import timeless.schemetypes.models import timeless.restaurants.models import timeless.reservations.models import timeless.roles.models import timeless.items.models import timeless.employees.models import timeless.companies.models
def app(): db_fd, db_path = tempfile.mkstemp() app = create_app("config.TestingConfig") app_context = app.test_request_context() app_context.push() DB.create_all() yield app DB.session.remove() DB.drop_all() os.close(db_fd) os.unlink(db_path)
class TableShape(DB.Model): """Model for a Table's Shape.""" __tablename__ = "table_shapes" id = DB.Column(DB.Integer, primary_key=True, autoincrement=True) description = DB.Column(DB.String, nullable=True) picture = DB.Column(DB.String, nullable=False) def __repr__(self): return "<TableShape %r>" % self.picture
class Floor(DB.Model): """Model for floor business entity. A Location may have 1 or more floors. """ __tablename__ = "floors" id = DB.Column(DB.Integer, primary_key=True, autoincrement=True) location_id = DB.Column(DB.Integer, DB.ForeignKey("locations.id")) description = DB.Column(DB.String, nullable=True) location = DB.relationship("Location", back_populates="floors") def __repr__(self): return "<Floor %r>" % self.id
class Company(TimestampsMixin, DB.Model): """Model for company business entity. @todo #3:30min Create management pages for Companies to list, create, edit and delete them. In the index page it should be possible to sort and filter for every column. """ __tablename__ = "companies" id = DB.Column(DB.Integer, primary_key=True, autoincrement=True) name = DB.Column(DB.String, unique=True, nullable=False) code = DB.Column(DB.String, unique=True, nullable=False) address = DB.Column(DB.String) locations = DB.relationship("Location", order_by="Location.id", back_populates="company") employees = DB.relationship("Employee", order_by="Employee.id", back_populates="company") roles = DB.relationship("Role", order_by="Role.id", back_populates="company") items = DB.relationship("Item", order_by="Item.id", back_populates="company") @validate_required("name", "code") def __init__(self, **kwargs): super(Company, self).__init__(**kwargs) def __repr__(self): return "<Company %r>" % self.name
class TableShape(DB.Model): """Model for a Table's Shape.""" __tablename__ = "table_shapes" id = DB.Column(DB.Integer, primary_key=True, autoincrement=True) description = DB.Column(DB.String, nullable=True) picture = DB.Column(DB.String, nullable=False) @validate_required("picture") def __init__(self, **kwargs): super(TableShape, self).__init__(**kwargs) def __repr__(self): return "<TableShape %r>" % self.picture
class TableReservation(DB.Model): """Association table for reservations and tables""" __tablename__ = "table_reservations" id = DB.Column(DB.Integer, primary_key=True, autoincrement=True) reservation_id = DB.Column(DB.Integer, DB.ForeignKey("reservations.id")) table_id = DB.Column(DB.Integer, DB.ForeignKey("tables.id")) table = DB.relationship("Table", back_populates="reservations") reservation = DB.relationship("Reservation", back_populates="tables")
class Reservation(TimestampsMixin, DB.Model): """Model for a Reservation """ __tablename__ = "reservations" id = DB.Column(DB.Integer, primary_key=True, autoincrement=True) start_time = DB.Column(DB.DateTime, nullable=False) end_time = DB.Column(DB.DateTime, nullable=False) customer_id = DB.Column(DB.Integer, DB.ForeignKey("customers.id")) num_of_persons = DB.Column(DB.DateTime, nullable=False) comment = DB.Column(DB.String, nullable=False) status = DB.Column(DB.Enum(ReservationStatus), nullable=False) tables = DB.relationship("TableReservation", back_populates="reservation") """Calculates the duration of the reservation""" def duration(self): return self.end_time - self.start_time def __repr__(self): return "<Reservation %r>" % self.id
def cleanup_db(app_test_context): DB.create_all() yield DB.session.remove() DB.drop_all()
class Location(PosterSyncMixin, DB.Model): """Model for location business entity""" __tablename__ = "locations" id = DB.Column(DB.Integer, primary_key=True, autoincrement=True) name = DB.Column(DB.String, unique=True, nullable=False) code = DB.Column(DB.String, unique=True, nullable=False) company_id = DB.Column(DB.Integer, DB.ForeignKey("companies.id")) country = DB.Column(DB.String, nullable=False) region = DB.Column(DB.String, nullable=False) city = DB.Column(DB.String, nullable=False) address = DB.Column(DB.String, nullable=False) longitude = DB.Column(DB.String, nullable=False) latitude = DB.Column(DB.String, nullable=False) type = DB.Column(DB.String, nullable=False) status = DB.Column(DB.String, nullable=False) comment = DB.Column(DB.String, nullable=True) company = DB.relationship("Company", back_populates="locations") floors = DB.relationship("Floor", order_by=Floor.id, back_populates="location") working_hours = DB.Column(DB.Integer, DB.ForeignKey("scheme_types.id")) closed_days = DB.Column(DB.Integer, DB.ForeignKey("scheme_types.id")) @validate_required("name", "code", "country", "region", "city", "type", "address", "longitude", "latitude", "status") def __init__(self, **kwargs): super(Location, self).__init__(**kwargs) def __repr__(self): return "<Location %r>" % self.name
class Employee(TimestampsMixin, DB.Model): """Model for employee business entity. @todo #4:30min Continue implementation. Employees should have its own management pages to list, create, edit and delete them. In the index page it should be possible to sort and filter for every column. Other possible actions are described in more detail in issue #4. Specific details about Employee default values are in another puzzle. """ __tablename__ = "employees" id = DB.Column(DB.Integer, primary_key=True, autoincrement=True) first_name = DB.Column(DB.String, nullable=False) last_name = DB.Column(DB.String, nullable=False) username = DB.Column(DB.String(15), unique=True, nullable=False) phone_number = DB.Column(DB.String, nullable=False) birth_date = DB.Column(DB.Date(), nullable=False) registration_date = DB.Column(DB.DateTime(), nullable=False) account_status = DB.Column(DB.String, nullable=False) user_status = DB.Column(DB.String, nullable=False) email = DB.Column(DB.String(300), nullable=False) password = DB.Column(DB.String(300), nullable=False) pin_code = DB.Column(DB.Integer, unique=True, nullable=False) comment = DB.Column(DB.String) company_id = DB.Column(DB.Integer, DB.ForeignKey("companies.id")) role_id = DB.Column(DB.Integer, DB.ForeignKey("roles.id"), nullable=True) company = DB.relationship("Company", back_populates="employees") items = DB.relationship("Item", back_populates="empolyee") history = DB.relationship("ItemHistory", back_populates="employee") @validate_required("username", "password", "first_name", "last_name", "phone_number", "birth_date", "email", "pin_code", "registration_date", "account_status", "user_status") def __init__(self, **kwargs): super(Employee, self).__init__(**kwargs) def __repr__(self): return "<Employee(username=%s)>" % self.username def validate_password(self, password): """ Validate user password """ return bcrypt_sha256.verify(password, self.password)
class Employee(TimestampsMixin, DB.Model): """Model for employee business entity.""" __tablename__ = "employees" id = DB.Column(DB.Integer, primary_key=True, autoincrement=True) first_name = DB.Column(DB.String, nullable=False) last_name = DB.Column(DB.String, nullable=False) username = DB.Column(DB.String(15), unique=True, nullable=False) phone_number = DB.Column(DB.String, nullable=False) birth_date = DB.Column(DB.Date(), nullable=False) registration_date = DB.Column(DB.DateTime(), nullable=False) account_status = DB.Column(DB.String, nullable=False) user_status = DB.Column(DB.String, nullable=False) email = DB.Column(DB.String(300), nullable=False) password = DB.Column(DB.String(300), nullable=False) pin_code = DB.Column(DB.Integer, unique=True, nullable=False) comment = DB.Column(DB.String) company_id = DB.Column(DB.Integer, DB.ForeignKey("companies.id")) role_id = DB.Column(DB.Integer, DB.ForeignKey("roles.id"), nullable=True) company = DB.relationship("Company", back_populates="employees") items = DB.relationship("Item", back_populates="empolyee") history = DB.relationship("ItemHistory", back_populates="employee") role = DB.relationship("Role", back_populates="employees") def __repr__(self): return "<Employee(username=%s)>" % self.username
class Location(PosterSyncMixin, DB.Model): """Model for location business entity""" __tablename__ = "locations" id = DB.Column(DB.Integer, primary_key=True, autoincrement=True) name = DB.Column(DB.String, unique=True, nullable=False) code = DB.Column(DB.String, unique=True, nullable=False) company_id = DB.Column(DB.Integer, DB.ForeignKey("companies.id")) country = DB.Column(DB.String, nullable=False) region = DB.Column(DB.String, nullable=False) city = DB.Column(DB.String, nullable=False) address = DB.Column(DB.String, nullable=False) longitude = DB.Column(DB.String, nullable=False) latitude = DB.Column(DB.String, nullable=False) type = DB.Column(DB.String, nullable=False) status = DB.Column(DB.String, nullable=False) comment = DB.Column(DB.String, nullable=True) company = DB.relationship("Company", back_populates="locations") floors = DB.relationship("Floor", order_by=Floor.id, back_populates="location") working_hours = DB.Column(DB.Integer, DB.ForeignKey("scheme_types.id")) closed_days = DB.Column(DB.Integer, DB.ForeignKey("scheme_types.id")) def __repr__(self): return "<Location %r>" % self.name @classmethod def merge_with_poster(cls, location, poster_location: dict): """ Method should return Location object with merged data from table entity and poster location dict @todo #343:30min Implement two class methods merge_with_poster and create_by_poster. merge_with_poster will merge entry entity with poster entity, we should make right fields mapping, as result returns Location instance. The same should be made with method create_by_poster, returns Location instance with data from poster_customer """ raise NotImplementedError() @classmethod def create_by_poster(cls, poster_location: dict): """ Method should return Location object with given data from poster_location dict """ raise NotImplementedError()
class Table(TimestampsMixin, PosterSyncMixin, DB.Model): """Model for a Table""" __tablename__ = "tables" id = DB.Column(DB.Integer, primary_key=True, autoincrement=True) name = DB.Column(DB.String, nullable=False) floor_id = DB.Column(DB.Integer, DB.ForeignKey("floors.id")) x = DB.Column(DB.Integer, nullable=False) y = DB.Column(DB.Integer, nullable=False) width = DB.Column(DB.Integer, nullable=False) height = DB.Column(DB.Integer, nullable=False) status = DB.Column(DB.Integer, nullable=False) max_capacity = DB.Column(DB.Integer, nullable=False) multiple = DB.Column(DB.Boolean, default=False) playstation = DB.Column(DB.Boolean, default=False) shape_id = DB.Column(DB.Integer, DB.ForeignKey("table_shapes.id")) min_capacity = DB.Column(DB.Integer, DB.ForeignKey("scheme_types.id")) deposit_hour = DB.Column(DB.Integer, DB.ForeignKey("scheme_types.id")) reservations = DB.relationship("TableReservation", back_populates="table") floor = DB.relationship("Floor", back_populates="tables") DB.UniqueConstraint(u"name", u"floor_id") def __repr__(self): return "<Table %r>" % self.name
class Employee(TimestampsMixin, DB.Model): """Model for employee business entity. @todo #4:30min Continue implementation. Employees should have its own management pages to list, create, edit and delete them. In the index page it should be possible to sort and filter for every column. Other possible actions are described in more detail in issue #4. Specific details about Employee default values are in another puzzle. @todo #4:30min Implement validate_required decorator for all the models in the timeless app that require mandatory parameters check. See Employee model as an example of how to use the decorator. Write tests to verify all the mandatory fields are checked. """ __tablename__ = "employees" id = DB.Column(DB.Integer, primary_key=True, autoincrement=True) first_name = DB.Column(DB.String, nullable=False) last_name = DB.Column(DB.String, nullable=False) username = DB.Column(DB.String(15), unique=True, nullable=False) phone_number = DB.Column(DB.String, nullable=False) birth_date = DB.Column(DB.Date(), nullable=False) registration_date = DB.Column(DB.DateTime(), nullable=False) account_status = DB.Column(DB.String, nullable=False) user_status = DB.Column(DB.String, nullable=False) email = DB.Column(DB.String(300), nullable=False) password = DB.Column(DB.String(300), nullable=False) pin_code = DB.Column(DB.Integer, unique=True, nullable=False) comment = DB.Column(DB.String) company_id = DB.Column(DB.Integer, DB.ForeignKey("companies.id")) company = DB.relationship("Company", back_populates="employees") items = DB.relationship("Item", back_populates="empolyee") history = DB.relationship("ItemHistory", back_populates="employee") @validate_required("username", "password", "first_name", "last_name", "phone_number", "birth_date", "email") def __init__(self, **kwargs): super(Employee, self).__init__(**kwargs) self.password = bcrypt_sha256.hash(kwargs.get("password")) self.pin_code = randint(1000, 9999) self.registration_date = datetime.utcnow() self.account_status = "Not Activated" self.user_status = "Working" self.created_on = datetime.utcnow() def __repr__(self): return "<Employee(username=%s)>" % self.username def validate_password(self, password): """ Validate user password """ return bcrypt_sha256.verify(password, self.password)
class Table(TimestampsMixin, PosterSyncMixin, DB.Model): """Model for a Table""" __tablename__ = "tables" id = DB.Column(DB.Integer, primary_key=True, autoincrement=True) name = DB.Column(DB.String, nullable=False) floor_id = DB.Column(DB.Integer, DB.ForeignKey("floors.id")) x = DB.Column(DB.Integer, nullable=False) y = DB.Column(DB.Integer, nullable=False) width = DB.Column(DB.Integer, nullable=False) height = DB.Column(DB.Integer, nullable=False) status = DB.Column(DB.Integer, nullable=False) max_capacity = DB.Column(DB.Integer, nullable=False) multiple = DB.Column(DB.Boolean, default=False) playstation = DB.Column(DB.Boolean, default=False) shape_id = DB.Column(DB.Integer, DB.ForeignKey("table_shapes.id")) min_capacity = DB.Column(DB.Integer, DB.ForeignKey("scheme_types.id")) deposit_hour = DB.Column(DB.Integer, DB.ForeignKey("scheme_types.id")) reservations = DB.relationship("TableReservation", back_populates="table") DB.UniqueConstraint(u"name", u"floor_id") def __repr__(self): return "<Table %r>" % self.name @classmethod def merge_with_poster(cls, table, poster_table: dict): """ Method should return Table object with merged data from table entity and poster table dict @todo #187:30min Implement two class methods merge_with_poster and create_by_poster. merge_with_poster will merge entry entity with poster entity, we should make right fields mapping, as result returns Table instance. The same should be made with method create_by_poster, returns Table instance with data from poster_table """ return cls() @classmethod def create_by_poster(cls, poster_table: dict): """ Method should return Table object with given data from poster_table dict """ poster_table return cls()
class Table(PosterSyncMixin, DB.Model): """Model for a Table""" __tablename__ = "tables" id = DB.Column(DB.Integer, primary_key=True, autoincrement=True) name = DB.Column(DB.String, nullable=False) floor_id = DB.Column(DB.Integer, DB.ForeignKey("floors.id")) x = DB.Column(DB.Integer, nullable=False) y = DB.Column(DB.Integer, nullable=False) width = DB.Column(DB.Integer, nullable=False) height = DB.Column(DB.Integer, nullable=False) status = DB.Column(DB.Integer, nullable=False) max_capacity = DB.Column(DB.Integer, nullable=False) multiple = DB.Column(DB.Boolean, default=False) playstation = DB.Column(DB.Boolean, default=False) shape_id = DB.Column(DB.Integer, DB.ForeignKey("table_shapes.id")) min_capacity = DB.Column(DB.Integer, DB.ForeignKey("scheme_types.id")) deposit_hour = DB.Column(DB.Integer, DB.ForeignKey("scheme_types.id")) created = DB.Column(DB.DateTime, nullable=False) updated = DB.Column(DB.DateTime, nullable=False) reservations = DB.relationship("TableReservation", back_populates="table") DB.UniqueConstraint(u"name", u"floor_id") @validate_required("name", "x", "y", "width", "height", "status", "max_capacity", "multiple", "playstation", "created", "updated") def __init__(self, **kwargs): super(Table, self).__init__(**kwargs) def __repr__(self): return "<Table %r>" % self.name
class Employee(TimestampsMixin, DB.Model): """Model for employee business entity.""" __tablename__ = "employees" id = DB.Column(DB.Integer, primary_key=True, autoincrement=True) first_name = DB.Column(DB.String, nullable=False) last_name = DB.Column(DB.String, nullable=False) username = DB.Column(DB.String(15), unique=True, nullable=False) phone_number = DB.Column(DB.String, nullable=False) birth_date = DB.Column(DB.Date(), nullable=False) registration_date = DB.Column(DB.DateTime(), nullable=False) account_status = DB.Column(DB.String, nullable=False) user_status = DB.Column(DB.String, nullable=False) email = DB.Column(DB.String(300), nullable=False) password = DB.Column(DB.String(300), nullable=False) pin_code = DB.Column(DB.Integer, unique=True, nullable=False) comment = DB.Column(DB.String) company_id = DB.Column(DB.Integer, DB.ForeignKey("companies.id")) role_id = DB.Column(DB.Integer, DB.ForeignKey("roles.id"), nullable=True) company = DB.relationship("Company", back_populates="employees") items = DB.relationship("Item", back_populates="empolyee") history = DB.relationship("ItemHistory", back_populates="employee") @validate_required("username", "password", "first_name", "last_name", "phone_number", "birth_date", "email", "pin_code", "registration_date", "account_status", "user_status") def __init__(self, **kwargs): super(Employee, self).__init__(**kwargs) def __repr__(self): return "<Employee(username=%s)>" % self.username def validate_password(self, password): """ Validate user password """ return bcrypt_sha256.verify(password, self.password)
def flush_db(app): DB.create_all() yield DB.session.remove() DB.drop_all()