class Product(db.Model): __tablename__ = 'products' id = db.Column(db.Integer, primary_key=True) description = db.Column(db.String(64)) image_file = db.Column(db.String(32), default='default.jpg') unit_cost = db.Column(db.Numeric(6, 2), nullable=False) is_available = db.Column(db.Boolean, nullable=False) code = db.Column(db.String(13), unique=True, nullable=False) category_id = db.Column(db.Integer, ForeignKey('categories.id'), nullable=False) category = relationship("Category", backref=backref('products', order_by=description)) __table_args__ = (CheckConstraint(unit_cost >= 0.00, name='unit_cost_positive'), ) def __init__(self, category_id, description: str, unit_cost, code: str, is_available=True): # This field is 'virtual'. It was declared in Category model as a # backref self.category_id = category_id self.description = description self.unit_cost = unit_cost self.is_available = is_available self.code = code def to_json(self) -> str: json_product = { 'id': self.id, 'category_id': self.category_id, 'description': self.description, 'unit_cost': str(self.unit_cost), 'is_available': self.is_available, 'code': self.code } return json_product @staticmethod def from_json(json_product) -> Product: category_id = json_product.get('category_id') description = json_product.get('description') unit_cost = decimal.Decimal(json_product.get('unit_cost')) code = json_product.get('code') return Product(category_id, description, unit_cost, code) def __eq__(self, other) -> bool: return self.code == other.code def __repr__(self) -> str: return '<Product %r %r %r>' % (self.description, self.unit_cost, self.is_available)
class User(db.Model): """ Using Concrete Table Inheritance Mapping. """ __metaclass__ = ABCMeta __abstract__ = True id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(64), nullable=False, index=True) phone_number = db.Column(db.String(11), nullable=False) def __init__(self, name, phone_number): self.name = name self.phone_number = phone_number
class Client(User): __tablename__ = 'clients' __mapper_args__ = {'concrete': True} identification = db.Column(db.String(9), unique=True) notifiable = db.Column(db.Boolean) address = db.Column(db.String(64)) status = db.Column(db.Boolean) amount = db.Column(db.Numeric(10, 2), default=0) def __init__(self, name, phone_number, identification, address, notifiable, status=True): super().__init__(name, phone_number) self.identification = identification self.notifiable = notifiable self.address = address self.status = status def to_json(self): json_client = { 'id': self.id, 'name': self.name, 'phone_number': self.phone_number, 'identification': self.identification, 'address': self.address, 'notifiable': self.notifiable, 'status': self.status, 'amount': str(self.amount) } return json_client @staticmethod def from_json(json_client): import uuid identification = uuid.uuid4().time_low name = json_client.get('name') phone_number = json_client.get('phone_number') address = json_client['address'] notifiable = json_client.get('notifiable') client = Client(name, phone_number, str(identification)[0:9], address, notifiable) return client
class Category(db.Model): __tablename__ = 'categories' id = db.Column(db.Integer, primary_key=True) title = db.Column(db.String(32), index=True, nullable=False) def __init__(self, title: str): self.title = title def to_json(self) -> str: json_product = {'id': self.id, 'title': self.title} return json_product @staticmethod def from_json(json_category) -> Category: title = json_category.get('title') return Category(title) def __repr__(self) -> str: return '<Category %r>' % self.title
class Clerk(User, UserMixin): __tablename__ = 'clerks' image = db.Column(db.String(256), default='default.png') email = db.Column(db.String(64), unique=True) password_hash = db.Column(db.String(128), nullable=False) __mapper_args__ = {'concrete': True} def __init__(self, name: str, phone_number: str, email: str, password: str): super().__init__(name, phone_number) self.email: str = email self.password: str = password def get_token(self, expires_sec=600) -> str: """ The token is an encrypted version of a dictionary that has the id of the user :param expires_sec: :return: """ s = Serializer(current_app.config['SECRET_KEY'], expires_sec) return s.dumps({'clerk_id': self.id}).decode('utf-8') def generate_auth_token(self, expiration=3600) -> str: s = Serializer(current_app.config['SECRET_KEY'], expires_in=expiration) return s.dumps({'clerk_id': self.id}).decode('ascii') @staticmethod def verify_auth_token(token: str) -> Union[Clerk, None]: s = Serializer(current_app.config['SECRET_KEY']) try: data = s.loads(token) except SignatureExpired: return None # valid token, but expired except BadSignature: return None # invalid token clerk = Clerk.query.get(data['clerk_id']) return clerk @property def password(self) -> None: raise AttributeError('password is not a readable attribute') @password.setter def password(self, password: str) -> None: self.password_hash = generate_password_hash(password) def verify_password(self, password: str): return check_password_hash(self.password_hash, password) def to_json(self) -> str: token = self.generate_auth_token(3600) duration = datetime.now() + timedelta(hours=1) json_clerk = { 'id': self.id, 'email': self.email, 'name': self.name, 'phone_number': self.phone_number, 'profile_pic': self.image, 'token': { 'value': token, 'expiration_time': str(duration) } } return json_clerk def __repr__(self) -> str: return '<Atendente %r %r>' % (self.name, self.email)