class Application(ModelBase): user_id = db.Column( db.Integer, db.ForeignKey('user.id', ondelete='CASCADE'), nullable=False, ) company_name = db.Column(db.String(255), nullable=False, index=True) application_date = db.Column(db.DateTime, nullable=False, default=datetime.datetime.utcnow) application_notes = db.Column(db.Text, nullable=True) position = db.Column(db.String(255), nullable=False, index=True) user = db.relationship( 'User', backref=db.backref('applications', lazy='dynamic'), ) events = db.relationship( 'ApplicationEvent', backref='application', lazy='dynamic', ) contacts = db.relationship( 'ApplicationContact', backref='application', lazy='dynamic', ) keywords = db.relationship('Keyword', secondary=application_keyword, backref=db.backref('applications', lazy='dynamic'), lazy='dynamic')
class Comment(db.Model): __tablename__ = 'comments' id = db.Column(db.Integer, primary_key=True) username = db.Column(db.String(20), nullable=False) comment = db.Column(db.String(255), nullable=False) post_id = db.Column(db.Integer, db.ForeignKey('posts.id'), nullable=False) created_at = db.Column(db.DateTime, default=datetime.utcnow, nullable=False) updated_at = db.Column(db.DateTime, default=datetime.utcnow, nullable=False, onupdate=datetime.now()) post = db.relationship("Post", backref=db.backref("posts", lazy=True)) def __init__(self, username, comment, post_id): self.username = username self.comment = comment self.post_id = post_id def json(self): return { "id": self.id, "username": self.username, "comment": self.comment, "post_id": self.post_id, "created_at": str(self.created_at), "updated_at": str(self.updated_at) } def create(self): db.session.add(self) db.session.commit() return self @classmethod def find_all(cls): comments = Comment.query.all() return [comment.json() for comment in comments] @classmethod def find_by_id(cls, id): return Comment.query.filter_by(id=id).first() @classmethod def delete(cls, id): comment = Comment.find_by_id(id) db.session.delete(comment) db.session.commit() return comment.json() @classmethod def update(cls, id, fields): comment = Comment.find_by_id(id) for key in field: setattr(comment, key, fields[key]) db.session.commit() return comment.json()
class PositionAccomplishment(ModelBase): position_id = db.Column( db.Integer, db.ForeignKey('resume_position.id', ondelete='CASCADE'), nullable=False, ) description = db.Column(db.Text, nullable=False) resume_position = db.relationship('ResumePosition', backref=db.backref('accomplishments', lazy='dynamic')) keywords = db.relationship('Keyword', secondary=accomplishment_keyword, backref=db.backref('accomplishments', lazy='dynamic'), lazy='dynamic')
class Hat(db.Model): __tablename__ = "hat" id = db.Column(db.Integer, primary_key=True) colour = db.Column(db.Enum(Colour)) char_id = db.Column(db.Integer, db.ForeignKey('character.id')) # Creates the one to one relationship character = db.relationship("Character", backref=db.backref("children", cascade="all,delete", passive_deletes=True)) def __init__(self, id, colour): self.id = id self.colour = colour
class Post(db.Model): __tablename__ = 'posts' id = db.Column(db.Integer, primary_key=True) user_id = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=False) username = db.Column(db.String(255), nullable=False) image = db.Column(db.String(255), nullable=False) description = db.Column(db.Text, nullable=False) bid = db.Column(db.Float, nullable=False) created_at = db.Column(db.DateTime, default=str(datetime.utcnow()), nullable=False) updated_at = db.Column(db.DateTime, default=datetime.utcnow(), nullable=False, onupdate=datetime.now()) user = db.relationship('User', backref=db.backref('users', lazy=True)) def __init__(self, user_id, username, image, bid, description): self.user_id = user_id self.username = username self.image = image self.bid = bid self.description = description def json(self): return { "id": self.id, "user_id": self.user_id, "username": self.username, "image": self.image, "bid": self.bid, "description": self.description, "created_at": str(self.created_at), "updated_at": str(self.updated_at) } def create(self): db.session.add(self) db.session.commit() return self @classmethod def find_all(cls): return Post.query.order_by(Post.bid.desc()).all() @classmethod def find_by_id(cls, post_id): post = Post.query.filter_by(id=post_id).first() return post
class Keyword(ModelBase): __table_args__ = (db.UniqueConstraint('user_id', 'keyword', name='keyword_user_unique'), ) user_id = db.Column( db.Integer, db.ForeignKey('user.id', ondelete='CASCADE'), nullable=False, ) keyword = db.Column(db.String(50), nullable=False, index=True) user = db.relationship( 'User', backref=db.backref('keywords', lazy='dynamic'), )
class User(db.Model): __tablename__ = 'user' id = db.Column( db.Integer, name='id', primary_key=True, nullable=False ) name = db.Column( db.String(100), name='name', unique=True, nullable=False ) email = db.Column( db.String(100), name='email', nullable=False, unique=True ) password = db.Column( db.String(100), name='password', nullable=False ) roles = db.relationship( "Role", secondary='user_role', backref=db.backref('user'), single_parent=True ) def set_password(self, password): """Set password.""" bcrypt = Bcrypt(current_app) self.password = bcrypt.generate_password_hash(password) def check_password(self, value): """Check password.""" bcrypt = Bcrypt(current_app) return bcrypt.check_password_hash(self.password, value)
class ApplicationEvent(ModelBase): application_id = db.Column( db.Integer, db.ForeignKey('application.id', ondelete='CASCADE'), nullable=False, ) event_time = db.Column(db.DateTime, nullable=False, default=datetime.datetime.utcnow) event_type = db.Column(db.String(255), nullable=False, index=True) event_description = db.Column(db.String(255), nullable=False, index=True) application_notes = db.Column(db.Text, nullable=True) contacts = db.relationship('ApplicationContact', secondary=event_contacts, backref=db.backref('events', lazy='dynamic'), lazy='dynamic')
class User(db.Model): __tablename__ = 'users' id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String, nullable=False) email = db.Column(db.String, nullable=False, unique=True) password_digest = db.Column(db.String(255), nullable=False) created_at = db.Column(db.DateTime, default=datetime.utcnow, nullable=False) updated_at = db.Column(db.DateTime, default=datetime.utcnow(), nullable=False, onupdate=datetime.utcnow) posts = db.relationship("Post", cascade='all', backref=db.backref('posts', lazy=True)) def __init__(self, name, email, password_digest): self.name = name self.email = email self.password_digest = password_digest def json(self): return { "name": self.name, "email": self.email, "password_digest": self.password_digest, "created_at": str(self.created_at), "updated_at": str(self.updated_at) } def create(self): db.session.add(self) db.session.commit() return self.json() @classmethod def find_one(cls, email): user = User.query.filter_by(email=email).first() return user
class ResumePosition(ModelBase): user_id = db.Column( db.Integer, db.ForeignKey('user.id', ondelete='CASCADE'), nullable=False, ) company_name = db.Column(db.String(255), nullable=False, index=True) position_title = db.Column(db.String(255), nullable=False, index=True) position_start_date = db.Column( db.DateTime, nullable=False, default=datetime.datetime.utcnow, ) position_end_date = db.Column(db.DateTime, nullable=True) position_start_title = db.Column(db.String(255), nullable=True, index=True) starting_salary = db.Column(db.Integer, nullable=True, index=True) salary = db.Column(db.Integer, nullable=True, index=True) salary_rate = db.Column(db.String(255), nullable=True) description = db.Column(db.Text, nullable=True) user = db.relationship( 'User', backref=db.backref('resume_positions', lazy='dynamic'), )
class Offer(PcObject, Model, ExtraDataMixin, DeactivableMixin, ProvidableMixin): # We redefine this so we can reference it in the baseScore column_property id = Column(BigInteger, primary_key=True, autoincrement=True) productId = Column(BigInteger, ForeignKey("product.id"), index=True, nullable=False) product = relationship('Product', foreign_keys=[productId], backref='offers') venueId = Column(BigInteger, ForeignKey("venue.id"), nullable=False, index=True) venue = relationship('Venue', foreign_keys=[venueId], backref='offers') bookingEmail = Column(String(120), nullable=True) type = Column(String(50), CheckConstraint("type != 'None'"), index=True, nullable=False) name = Column(String(140), nullable=False) description = Column(Text, nullable=True) conditions = Column(String(120), nullable=True) ageMin = Column(Integer, nullable=True) ageMax = Column(Integer, nullable=True) url = Column(String(255), nullable=True) mediaUrls = Column(ARRAY(String(220)), nullable=False, default=[]) durationMinutes = Column(Integer, nullable=True) isNational = Column(Boolean, server_default=false(), default=False, nullable=False) dateCreated = Column(DateTime, nullable=False, default=datetime.utcnow) baseScore = column_property( select([func.coalesce(func.sum(Criterion.scoreDelta), 0)]).where( and_(Criterion.id == OfferCriterion.criterionId, (OfferCriterion.offerId == id)))) criteria = relationship('Criterion', backref=db.backref('criteria', lazy='dynamic'), secondary='offer_criterion') def errors(self): api_errors = super(Offer, self).errors() if self.venue: venue = self.venue else: venue = Venue.query.get(self.venueId) if self.isDigital and not venue.isVirtual: api_errors.add_error( 'venue', 'Une offre numérique doit obligatoirement être associée au lieu "Offre en ligne"' ) elif not self.isDigital and venue.isVirtual: api_errors.add_error( 'venue', 'Une offre physique ne peut être associée au lieu "Offre en ligne"' ) if self.isDigital and self._type_can_only_be_offline(): api_errors.add_error( 'url', 'Une offre de type {} ne peut pas être numérique'.format( self._get_label_from_type_string())) return api_errors def update_with_product_data(self, product_dict: dict): owning_offerer = self.product.owningOfferer if owning_offerer and owning_offerer == self.venue.managingOfferer: self.product.populate_from_dict(product_dict) @property def dateRange(self): if ProductType.is_thing(self.type) or not self.stocks: return DateTimes() start = min([stock.beginningDatetime for stock in self.stocks]) end = max([stock.endDatetime for stock in self.stocks]) return DateTimes(start, end) @property def lastStock(self): query = Stock.queryNotSoftDeleted() return query.join(Offer) \ .filter(Offer.id == self.id) \ .order_by(desc(Stock.bookingLimitDatetime)) \ .first() @property def hasActiveMediation(self): return any(map(lambda m: m.isActive, self.mediations)) @property def offerType(self): all_types = list(ThingType) + list(EventType) for possible_type in all_types: if str(possible_type) == self.type: return possible_type.as_dict() @property def isEvent(self): return ProductType.is_event(self.type) @property def isThing(self): return ProductType.is_thing(self.type) @property def isDigital(self): return self.url is not None and self.url != '' @property def isEditable(self): return self.lastProviderId is None @property def isFinished(self): return all(map(lambda s: not s.isBookable, self.stocks)) @property def isFullyBooked(self): if self._has_unlimited_stock(): return False bookable_stocks = list(filter(lambda s: s.isBookable, self.stocks)) total_quantity = 0 for stock in bookable_stocks: bookings = filter(lambda b: not b.isCancelled, stock.bookings) total_quantity += sum(map(lambda s: s.quantity, bookings)) available_stocks = sum( map(lambda s: s.available if s.isBookable else 0, self.stocks)) return total_quantity >= available_stocks @property def activeMediation(self): sorted_by_date_asc = sorted(self.mediations, key=lambda m: m.dateCreated) sorted_by_date_desc = reversed(sorted_by_date_asc) only_active = list(filter(lambda m: m.isActive, sorted_by_date_desc)) return only_active[0] if only_active else None @property def stockAlertMessage(self) -> str: non_deleted_stocks = [ stock for stock in self.stocks if not stock.isSoftDeleted ] total_number_stocks = len(non_deleted_stocks) number_of_empty_stocks = len( list( filter(lambda s: s.available == 0 or s.remainingQuantity == 0, non_deleted_stocks))) remaining_for_all_stocks = sum( map(lambda s: s.remainingQuantity, filter(lambda s: s.available, non_deleted_stocks))) if total_number_stocks == 0: return 'pas encore de stock' if self.isThing else 'pas encore de places' if all([s.available is None for s in non_deleted_stocks]): return 'illimité' if self.isFullyBooked: return 'plus de stock' if self.isThing else 'plus de places pour toutes les dates' if number_of_empty_stocks >= 1: offer_word = pluralize(number_of_empty_stocks, 'offre') stock_or_place = 'stock' if self.isThing else 'places' return f'plus de {stock_or_place} pour {number_of_empty_stocks} {offer_word}' if not self.isFullyBooked: remaining_stock_word = 'en stock' if self.isThing else pluralize( remaining_for_all_stocks, 'place') return f'encore {remaining_for_all_stocks} {remaining_stock_word}' def _has_unlimited_stock(self): return any(map(lambda s: s.available is None, self.stocks)) def _type_can_only_be_offline(self): offline_only_things = filter( lambda thing_type: thing_type.value['offlineOnly'], ThingType) offline_only_types_for_things = map(lambda x: x.__str__(), offline_only_things) return self.type in offline_only_types_for_things def _get_label_from_type_string(self): matching_type_thing = next( filter(lambda thing_type: str(thing_type) == self.type, ThingType)) return matching_type_thing.value['proLabel']