from app import db from flask_security import UserMixin, RoleMixin roles_users = db.Table('roles_users', db.Column('user_id', db.Integer(), db.ForeignKey('user.id')), db.Column('role_id', db.Integer(), db.ForeignKey('role.id'))) vehicles_consumables = db.Table('vehicles_consumables', db.Column('vehicle_id', db.Integer(), db.ForeignKey('vehicle.id')), db.Column('consumable_id', db.Integer(), db.ForeignKey('consumable.id'))) users_fillingstations = db.Table('users_fillingstations', db.Column('user_id', db.Integer(), db.ForeignKey('user.id')), db.Column('fillingstation_id', db.Integer(), db.ForeignKey('filling_station.int_id'))) class Role(db.Model, RoleMixin): """ Entity to handle different roles for users: Typically user and admin exist """ id = db.Column(db.Integer(), primary_key=True) name = db.Column(db.String(80), unique=True) description = db.Column(db.String(255)) def __str__(self): return self.name def __hash__(self): return hash(self.name) class User(db.Model, UserMixin): """ Entity to represent a user including login data and links to roles and vehicles. """ id = db.Column(db.Integer, primary_key=True) email = db.Column(db.String(255), unique=True) password = db.Column(db.String(255)) active = db.Column(db.Boolean()) confirmed_at = db.Column(db.DateTime()) home_lat = db.Column(db.Numeric(2, 5), default=0) home_long = db.Column(db.Numeric(2, 5), default=0) home_zoom = db.Column(db.Integer(), default=0) vehicles = db.relationship( 'Vehicle' ) roles = db.relationship( 'Role', secondary=roles_users, backref=db.backref('users', lazy='dynamic') ) favourite_filling_stations = db.relationship( 'FillingStation', secondary=users_fillingstations ) def __repr__(self): return '' % (self.id, self.owner_id, self.name) class Pitstop(db.Model): """ Entity to represent a pitstop for a single consumable. Attributes: * the date of the pitstop * the odometer of the pitstop * the id of the fuelled consumable * amount of consumable used * the costs of the consumable * the id of the vehicle that was refuelled """ id = db.Column(db.Integer, primary_key=True) date = db.Column(db.Date) odometer = db.Column(db.Integer) consumable_id = db.Column(db.Integer, db.ForeignKey('consumable.id')) amount = db.Column(db.Numeric(5, 2)) costs = db.Column(db.Numeric(5, 2), default=0) vehicle_id = db.Column(db.Integer, db.ForeignKey('vehicle.id')) # short cut to access the fuelled consumable of the pitstop consumable = db.relationship('Consumable') # this uniqueness constraint makes sure that for each consumable and each vehicle only one pitstop exists at the # same odometer __table_args__ = (db.UniqueConstraint('odometer', 'consumable_id', 'vehicle_id', name='_odometer_consumable_vehicle_uniq'),) def __init__(self, odometer, amount, date, costs, consumable_id): self.odometer = odometer self.amount = amount self.date = date self.costs = costs self.consumable_id = consumable_id def __repr__(self): return '' % \ (self.odometer, self.amount, self.date, self.vehicle_id, self.consumable_id) class Consumable(db.Model): """ Entity to represent a material that be consumed by a vehilce. Attributes: * name (must be globally unique) * unit """ id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(255), unique=True) ext_id = db.Column(db.String(255)) unit = db.Column(db.String(255)) vehicles = db.relationship( 'Vehicle', secondary=vehicles_consumables ) def __init__(self, name, ext_id, unit): self.name = name self.ext_id = ext_id self.unit = unit def __repr__(self): return '' % (self.name, self.unit) class Service(db.Model): id = db.Column(db.Integer, primary_key=True) date = db.Column(db.Date) odometer = db.Column(db.Integer) vehicle_id = db.Column(db.Integer, db.ForeignKey('vehicle.id')) costs = db.Column(db.Numeric(10, 2), default=0) description = db.Column(db.String(4096)) def __init__(self, date, odometer, vehicle_id, costs, description): self.description = description self.costs = costs self.date = date self.odometer = odometer self.vehicle_id = vehicle_id def __repr__(self): return '' % \ (self.odometer, self.date, self.vehicle_id, self.costs, self.description) class FillingStation(db.Model): int_id = db.Column(db.Integer, primary_key=True) id = db.Column(db.String(40), unique=True, nullable=False) name = db.Column(db.Text(), nullable=False) street = db.Column(db.Text(), nullable=False) place = db.Column(db.Text(), nullable=False) houseNumber = db.Column(db.Text()) postCode = db.Column(db.Integer(), nullable=False) brand = db.Column(db.Text(), nullable=False) lat = db.Column(db.Numeric(2, 5), nullable=False) lng = db.Column(db.Numeric(2, 5), nullable=False) def as_dict(self): res = {} for c in self.__table__.columns: val = getattr(self, c.name) import decimal if isinstance(val, decimal.Decimal): val = float(val) val = str(val) res[c.name] = val return res