class BaseModel(CommonModel): __abstract__ = True is_active = db.Column(db.Boolean(), nullable=False, default=True, server_default='1') is_deleted = db.Column(db.Boolean(), nullable=False, default=False, server_default='0')
class CommonIsDeletedModel(db.Model): __abstract__ = True is_deleted = db.Column(db.Boolean(), nullable=False, default=False, server_default='1')
class DocReceiveRecord(db.Model): __tablename__ = 'doc_receive_records' id = db.Column(db.Integer, primary_key=True, autoincrement=True) predefined_comment = db.Column( db.String(255), info={ 'label': 'Predefined Comment', 'choices': [(c, c) for c in [u'แจ้งเพื่อทราบ', u'แจ้งเพื่อพิจารณา', u'ขอความร่วมมือเข้าร่วม']] }) comment = db.Column(db.Text, info={'label': 'Additional Comment'}) sent_at = db.Column(db.DateTime(timezone=True)) sender_id = db.Column(db.ForeignKey('staff_account.id')) round_org_id = db.Column(db.ForeignKey('doc_round_orgs.id')) round_org = db.relationship(DocRoundOrg, backref=db.backref('sent_records', lazy='dynamic')) doc_id = db.Column(db.ForeignKey('doc_documents.id')) rejected = db.Column(db.Boolean(), default=False) members = db.relationship(StaffPersonalInfo, secondary=receipt_receivers) sender = db.relationship(StaffAccount) doc = db.relationship(DocDocument, backref=db.backref('doc_receipts', lazy='dynamic', cascade='all, delete-orphan'))
class User(db.Model): __tablename__ = 'users' id = db.Column(db.BigInteger, primary_key=True) username = db.Column(db.String(255), unique=True, nullable=False) password = db.Column(db.UnicodeText, nullable=False) first_name = db.Column(db.UnicodeText, nullable=False) last_name = db.Column(db.UnicodeText, nullable=False) title = db.Column(db.UnicodeText, nullable=False) email = db.Column(db.String(255), unique=True, nullable=False) enabled = db.Column(db.Boolean(), nullable=False, default=True, server_default='1') @property def full_name(self): return ' '.join([self.first_name, self.last_name]) # Required for flask-login @property def is_authenticated(self): return True def is_active(self): return True def is_anonymous(self): return False def get_id(self): return str(self.id)
class Article(Base): aid = db.Column(db.Integer, primary_key=True) uid = db.Column(db.Integer) cid = db.Column(db.Integer) title = db.Column(db.String(255)) content = db.Column(db.Text) picture = db.Column(db.String(2048)) can_show = db.Column(db.Boolean()) @classmethod def create_new(cls, uid, cid, title, content, picture): article = cls() article.uid = uid article.cid = cid article.title = title article.content = content article.picture = picture article.can_show = 1 db.session.add(article) db.session.commit() @classmethod def update(cls, article): cls.query.filter_by(aid=article.aid).update({ "title": article.title, "content": article.content, }) db.session.commit() @classmethod def delete(cls, id): cls.query.filter_by(aid=id).delete() db.session.commit() @classmethod def get_last_by_limit(cls, limit): articles = cls.query.filter_by(can_show=1).order_by( desc(cls.date_created)).limit(limit).all() return articles @classmethod def get_article_by_id(cls, id): article = cls.query.filter_by(aid=id).first() if article.can_show: return article else: return None @classmethod def get_all_article_of_club(cls, clubid): articles = cls.query.filter_by(cid=clubid, can_show=1).all() if articles: return articles else: return []
class VehicleBooking(db.Model): __tablename__ = 'scheduler_vehicle_bookings' id = db.Column('id', db.Integer(), primary_key=True, autoincrement=True) vehicle_id = db.Column('vehicle_id', db.ForeignKey('scheduler_vehicle_resources.id'), nullable=False) vehicle = db.relationship('VehicleResource', backref=db.backref('bookings')) title = db.Column('title', db.String(255), nullable=False) init_milage = db.Column('init_milage', db.Integer, nullable=True) end_milage = db.Column('end_milage', db.Integer, nullable=True) toll_fee = db.Column('toll_fee', db.Float(), default=0.0) distance = db.Column('distance', db.Integer, nullable=True) init_location = db.Column('init_location', db.String(255), nullable=True) destination = db.Column('destination', db.String(255), nullable=True) start = db.Column('start', db.DateTime(timezone=True), nullable=False) end = db.Column('end', db.DateTime(timezone=True), nullable=False) iocode_id = db.Column('iocode_id', db.ForeignKey('iocodes.id')) iocode = db.relationship('IOCode', backref=db.backref('vehicle_bookings')) org_id = db.Column('org_id', db.ForeignKey('orgs.id')) org = db.relationship('Org', backref=db.backref('vehicle_bookings')) num_passengers = db.Column('num_passengers', db.Integer()) approved = db.Column('approved', db.Boolean(), default=False) closed = db.Column('closed', db.Boolean(), default=False) created_at = db.Column('created_at', db.DateTime(timezone=True), server_default=func.now()) created_by = db.Column('created_by', db.ForeignKey('staff_account.id')) updated_at = db.Column('updated_at', db.DateTime(timezone=True), server_default=None) updated_by = db.Column('updated_by', db.ForeignKey('staff_account.id')) cancelled_at = db.Column('cancelled_at', db.DateTime(timezone=True), server_default=None) cancelled_by = db.Column('cancelled_by', db.ForeignKey('staff_account.id')) approved_by = db.Column('approved_by', db.ForeignKey('staff_account.id')) approved_at = db.Column('approved_at', db.DateTime(timezone=True), server_default=None) desc = db.Column('desc', db.Text()) google_event_id = db.Column('google_event_id', db.String(64)) google_calendar_id = db.Column('google_calendar_id', db.String(255))
class Alumni(db.Model): __tablename__ = "alumni" alumni_id = db.Column(db.Integer, primary_key=True, autoincrement=True) alumni_uuid = db.Column(db.String(50), unique=True) odoo_contact_id = db.Column(db.String(50), unique=True, nullable=False) email = db.Column(db.String(100), unique=True) password = db.Column(db.String(100)) user_confirmed = db.Column(db.Boolean()) allow_show_contacts = db.Column(db.Boolean()) update_form = db.relationship("UpdateForm", back_populates="alumni") def __init__(self, odoo_contact_id, email, password, allow_show_contacts): self.alumni_uuid = str(uuid.uuid4()) self.odoo_contact_id = odoo_contact_id self.email = email self.password = flask_bcrypt.generate_password_hash(password).decode() self.user_confirmed = False self.allow_show_contacts = allow_show_contacts def check_password(self, password): return flask_bcrypt.check_password_hash(self.password, password)
class SmartClassOnlineAccountEvent(db.Model): __tablename__ = 'smartclass_scheduler_online_account_events' id = db.Column('id', db.Integer(), primary_key=True, autoincrement=True) account_id = db.Column( 'account_id', db.ForeignKey('smartclass_scheduler_online_accounts.id'), nullable=False) title = db.Column('title', db.String(255), nullable=False, info={'label': u'กิจกรรม'}) start = db.Column('start', db.DateTime(timezone=True), nullable=False, info={'label': u'เริ่ม'}) end = db.Column('end', db.DateTime(timezone=True), nullable=False, info={'label': u'สิ้นสุด'}) occupancy = db.Column('occupancy', db.Integer(), info={'label': u'ผู้เข้าร่วม'}) approved = db.Column('approved', db.Boolean(), default=True) created_at = db.Column('created_at', db.DateTime(timezone=True), server_default=func.now()) created_by = db.Column('created_by', db.ForeignKey('staff_account.id')) creator = db.Column('creator', db.String(), nullable=True, info={'label': u'ชื่อผู้ลงทะเบียน'}) updated_at = db.Column('updated_at', db.DateTime(timezone=True), server_default=None) updated_by = db.Column('updated_by', db.ForeignKey('staff_account.id')) cancelled_at = db.Column('cancelled_at', db.DateTime(timezone=True), server_default=None) cancelled_by = db.Column('cancelled_by', db.ForeignKey('staff_account.id')) approved_by = db.Column('approved_by', db.ForeignKey('staff_account.id')) approved_at = db.Column('approved_at', db.DateTime(timezone=True), server_default=None) note = db.Column('note', db.Text(), info={'label': u'หมายเหตุ'}) account = db.relationship(SmartClassOnlineAccount, backref=db.backref('events'))
class Admin(db.Model): __tablename__ = "admin" admin_id = db.Column(db.Integer, primary_key=True) first_name = db.Column(db.String(100)) last_name = db.Column(db.String(100)) username = db.Column(db.String(100), unique=True, nullable=False) photo_url = db.Column(db.String(100)) is_superadmin = db.Column(db.Boolean()) repetition = db.relationship("Repetition", back_populates="admin") def __init__(self, admin_id, first_name, last_name, username, photo_url, is_superadmin=False): self.admin_id = admin_id self.first_name = first_name self.last_name = last_name self.username = username self.photo_url = photo_url self.is_superadmin = is_superadmin
class User(db.Model): __tablename__ = 'users' id = db.Column(db.BigInteger, primary_key=True) username = db.Column(db.String(255), unique=True, nullable=False) password = db.Column(db.UnicodeText, nullable=False) first_name = db.Column(db.UnicodeText, nullable=False) last_name = db.Column(db.UnicodeText, nullable=False) role = db.Column(db.UnicodeText, nullable=False) email = db.Column(db.String(255), unique=True, nullable=False) enabled = db.Column(db.Boolean(), nullable=False, default=True, server_default='1') client_services = db.relationship('ClientService', cascade='all, delete-orphan', backref='users') worker_services = db.relationship('WorkerService', cascade='all, delete-orphan', backref='users') @property def full_name(self): return ' '.join([self.first_name, self.last_name]) @property def is_admin(self): return self.role == 'admin' # Required for flask-login @property def is_authenticated(self): return True def is_active(self): return True def is_anonymous(self): return False def get_id(self): return str(self.id)
class JobDetails(db.Model): """ [summary] Args: UserMixin ([type]): [description] db ([type]): [description] """ __tablename__ = "jobs" job_id = db.Column(db.Integer(), nullable=False, autoincrement=True, primary_key=True) job_title = db.Column(db.String(250), nullable=True) company_name = db.Column(db.String(250), nullable=True) payscale = db.Column(db.String(250), nullable=True) location = db.Column(db.String(250), nullable=True) parent_source = db.Column(db.String(250), nullable=True) job_type = db.Column(db.String(250), nullable=True) company_type = db.Column(db.String(250), nullable=True) description = db.Column(db.String(250), nullable=True) date_posted = db.Column(db.String(250), nullable=True) active = db.Column(db.Boolean(), nullable=True)
class RoomEvent(db.Model): __tablename__ = 'scheduler_room_reservations' id = db.Column('id', db.Integer(), primary_key=True, autoincrement=True) room_id = db.Column('room_id', db.ForeignKey('scheduler_room_resources.id'), nullable=False) category_id = db.Column('category_id', db.ForeignKey('scheduler_event_categories.id')) category = db.relationship('EventCategory', backref=db.backref('events')) title = db.Column('title', db.String(255), nullable=False) start = db.Column('start', db.DateTime(timezone=True), nullable=False) end = db.Column('end', db.DateTime(timezone=True), nullable=False) iocode_id = db.Column('iocode_id', db.ForeignKey('iocodes.id')) occupancy = db.Column('occupancy', db.Integer()) # number of sets of food/refreshment requested refreshment = db.Column('refreshment', db.Integer(), default=0) request = db.Column('request', db.Text()) # comma separated list of things approved = db.Column('approved', db.Boolean(), default=True) created_at = db.Column('created_at', db.DateTime(timezone=True), server_default=func.now()) created_by = db.Column('created_by', db.ForeignKey('staff_account.id')) updated_at = db.Column('updated_at', db.DateTime(timezone=True), server_default=None) updated_by = db.Column('updated_by', db.ForeignKey('staff_account.id')) cancelled_at = db.Column('cancelled_at', db.DateTime(timezone=True), server_default=None) cancelled_by = db.Column('cancelled_by', db.ForeignKey('staff_account.id')) approved_by = db.Column('approved_by', db.ForeignKey('staff_account.id')) approved_at = db.Column('approved_at', db.DateTime(timezone=True), server_default=None) extra_items = db.Column('extra_items', db.JSON) note = db.Column('note', db.Text()) google_event_id = db.Column('google_event_id', db.String(64)) google_calendar_id = db.Column('google_calendar_id', db.String(255))
class DocDocumentReach(db.Model): __tablename__ = 'doc_document_reaches' id = db.Column(db.Integer, primary_key=True, autoincrement=True) reached_at = db.Column(db.DateTime(timezone=True)) reacher_id = db.Column(db.ForeignKey('staff_account.id')) reacher = db.relationship(StaffAccount, backref=db.backref('doc_reaches', lazy='dynamic')) doc_id = db.Column(db.ForeignKey('doc_documents.id')) starred = db.Column(db.Boolean(False)) note = db.Column(db.Text()) doc = db.relationship(DocDocument, backref=db.backref('reaches', lazy='dynamic', cascade='all, delete-orphan')) round_org_id = db.Column(db.ForeignKey('doc_round_orgs.id')) round_org = db.relationship(DocRoundOrg, backref=db.backref('doc_reaches', lazy='dynamic')) sender_comment = db.Column(db.Text()) receiver_comment = db.Column(db.Text()) receiver_commented_at = db.Column(db.DateTime(timezone=True)) created_at = db.Column(db.DateTime(timezone=True))
class UpdateForm(db.Model): """Namings as in Odoo. """ __tablename__ = "update_form" form_id = db.Column(db.Integer, primary_key=True, autoincrement=True) form_status = db.Column(db.String(100)) name = db.Column(db.String(100)) # full name in ukrainian birth_date = db.Column(db.Date()) image_1920 = db.Column( db.String(500000) ) # Odoo saves image as base64 encoded string, f*cking large str # email = db.Column(db.String(100)) # Do not allow to update email here, because we use email for login contact_country = db.Column(db.String(100)) # selection field contact_city = db.Column(db.String(100)) mobile = db.Column(db.String(15)) skype = db.Column(db.String(100)) telegram = db.Column(db.String(100)) viber = db.Column(db.String(100)) facebook_link = db.Column(db.String(100)) linkedin_link = db.Column(db.String(100)) diploma_naukma = db.Column(db.Boolean) bachelor_degree = db.Column(db.Boolean()) bachelor_faculty = db.Column(db.String(100)) # selection field bachelor_speciality = db.Column(db.String(100)) # selection field bachelor_year_in = db.Column(db.String(100)) # selection field bachelor_year_out = db.Column(db.String(100)) # selection field master_degree = db.Column(db.Boolean()) master_faculty = db.Column(db.String(100)) # selection field master_speciality = db.Column(db.String(100)) # selection field master_year_in = db.Column(db.String(100)) # selection field master_year_out = db.Column(db.String(100)) # selection field parent_id = db.Column( db.Integer) # company id in Odoo, many2one field in Odoo company_name = db.Column(db.String(100)) function = db.Column(db.String(100)) # job position # foreign keys alumni_id = db.Column(db.Integer, db.ForeignKey('alumni.alumni_id', onupdate="CASCADE", ondelete="NO ACTION"), nullable=False) alumni = db.relationship("Alumni", back_populates="update_form") operator_id = db.Column(db.Integer, db.ForeignKey('operator.operator_id', onupdate="CASCADE", ondelete="NO ACTION"), nullable=True) operator = db.relationship("Operator", back_populates="update_form") def __init__(self, name, birth_date, image_1920, contact_country, contact_city, mobile, skype, telegram, viber, facebook_link, linkedin_link, diploma_naukma, bachelor_degree, bachelor_faculty, bachelor_speciality, bachelor_year_in, bachelor_year_out, master_degree, master_faculty, master_speciality, master_year_in, master_year_out, parent_id, company_name, function, alumni_id, operator_id): self.form_status = 'new' # TODO: create enum for the form statuses self.name = name self.birth_date = datetime.strptime(birth_date, '%Y-%m-%d').date() self.image_1920 = image_1920 self.contact_country = contact_country self.contact_city = contact_city self.mobile = mobile self.skype = skype self.telegram = telegram self.viber = viber self.facebook_link = facebook_link self.linkedin_link = linkedin_link self.diploma_naukma = diploma_naukma self.bachelor_degree = bachelor_degree self.bachelor_faculty = bachelor_faculty self.bachelor_speciality = bachelor_speciality self.bachelor_year_in = bachelor_year_in self.bachelor_year_out = bachelor_year_out self.master_degree = master_degree self.master_faculty = master_faculty self.master_speciality = master_speciality self.master_year_in = master_year_in self.master_year_out = master_year_out self.parent_id = parent_id self.company_name = company_name self.function = function self.alumni_id = alumni_id self.operator_id = operator_id def update(self, data): for key, item in data.items(): if hasattr(self, key): setattr(self, key, item) db.session.commit()
class UserEntity(db.Model, UserMixin, CRUDMixin): """ Stores the basic information about the user. Implements the functions as required by: https://flask-login.readthedocs.org/en/latest/ """ __tablename__ = 'User' id = db.Column("usrID", db.Integer, primary_key=True) email = db.Column("usrEmail", db.String(255), nullable=False, unique=True) first = db.Column("usrFirst", db.String(255), nullable=False) last = db.Column("usrLast", db.String(255), nullable=False) minitial = db.Column("usrMI", db.String(1), nullable=False) added_at = db.Column("usrAddedAt", db.DateTime, nullable=False, server_default='0000-00-00 00:00:00') modified_at = db.Column("usrModifiedAt", db.TIMESTAMP, nullable=False) email_confirmed_at = db.Column("usrEmailConfirmedAt", db.DateTime, nullable=False, server_default='0000-00-00 00:00:00') active = db.Column("usrIsActive", db.Boolean(), nullable=False, server_default='1') access_expires_at = db.Column("usrAccessExpiresAt", db.DateTime, nullable=False, server_default='0000-00-00 00:00:00') password_hash = db.Column("usrPasswordHash", db.String(255), nullable=False, server_default='') # @OneToMany roles = db.relationship(RoleEntity, secondary=UserRoleEntity.__tablename__, backref=db.backref('users'), lazy='dynamic') """ `lazy` defines when SQLAlchemy will load the data from the: 'select' (which is the default) means that SQLAlchemy will load the data as necessary in one go using a standard select statement. 'joined' tells SQLAlchemy to load the relationship in the same query as the parent using a JOIN statement. 'subquery' works like 'joined' but instead SQLAlchemy will use a subquery. 'dynamic' is special and useful if you have may items. Instead of loading the items SQLAlchemy will return another query object which you can further refine before loading them items. This is usually what you want if you expect more than a handful of items for this relationship. """ def is_active(self): """ An user can be blocked by setting a flag in the """ return self.active def is_expired(self): """ An user can be blocked by setting expiration date to yesterday""" return self.access_expires_at < datetime.today() def is_anonymous(self): """ Flag instances of valid users """ return False def is_authenticated(self): """ Returns True if the user is authenticated, i.e. they have provided valid credentials. (Only authenticated users will fulfill the criteria of login_required.) """ return True def get_id(self): """ The id encrypted in the session """ return unicode(self.id) def get_roles(self): """ Return text representation of user roles """ return [role.name for role in self.roles] def get_name(self): """ :rtype string :return concat(first, ' ', last) """ return "{} {}".format(self.first.encode('utf-8'), self.last.encode('utf-8')) def get_email_verification_token(self, salt, secret): """ :rtype string :return the email verification token stored in the """ return utils.get_email_token(self.email, salt, secret) def serialize(self): """Return object data for jsonification""" return { 'id': self.id, 'email': self.email, 'roles': [r.name for r in self.roles], 'first': self.first, 'last': self.last, 'minitial': self.minitial, 'is_active': True if self.active else False, 'is_expired': True if self.is_expired() else False, 'added_at': utils.localize_est_date(self.added_at), 'email_confirmed_at': utils.localize_est_datetime(self.email_confirmed_at), 'access_expires_at': utils.localize_est_datetime(self.access_expires_at) } def __repr__(self): return "<UserEntity (usrID: {0.id}, usrEmail: {0.email}, " \ "usrIsActive: {0.active})>".format(self)
class Resource(TimestampMixin, db.Model): __tablename__ = 'resources' id = db.Column(db.BigInteger, primary_key=True) category_id = db.Column(db.BigInteger, db.ForeignKey('categories.id', onupdate='CASCADE', ondelete='RESTRICT'), nullable=False) category = db.relationship('Category', backref='resources') user_id = db.Column(db.BigInteger, db.ForeignKey('users.id', onupdate='CASCADE', ondelete='CASCADE'), nullable=False) user = db.relationship('User', backref='resources') description = db.Column(db.UnicodeText(), nullable=True) type = db.Column(sau.ChoiceType(USER_RESOURCE_TYPES), index=True) quantity_available = db.Column(db.BigInteger) quantity_needed = db.Column(db.BigInteger) fulfilled = db.Column(db.Boolean, nullable=False, default=False, server_default='0') name = db.Column(db.UnicodeText(), nullable=False) picture = db.Column(db.UnicodeText()) requested = db.Column(db.Boolean(), nullable=True, default=False) def __setattr__(self, name, value): if name == 'picture': if value: filename = '{}.{}'.format(self.id, value.filename.split('.')[-1]) super().__setattr__( 'picture', upload_file(value, 'resource_pictures', filename)) else: super().__setattr__(name, value) @property def picture_url(self): if not self.picture: return None return file_url(self.picture) @property def quantity_remaining(self): if self.type != 'HAVE': return None fulfillment = ResourceFulfillment.query.filter( ResourceFulfillment.fulfilling_resource == self, ResourceFulfillment.confirmed_by_recipient == True, ) return self.quantity_available - sum( [f.fulfilled_quantity for f in fulfillment]) @property def quantity_fulfilled(self): if self.type != 'NEED': return None fulfillment = ResourceFulfillment.query.filter( ResourceFulfillment.fulfilled_resource == self, ResourceFulfillment.confirmed_by_recipient == True, ) return self.quantity_needed - sum( [f.fulfilled_quantity for f in fulfillment]) def serialize(self): return { 'id': self.id, 'name': self.name, 'category': self.category.name, 'user_id': self.user.id, 'type': self.type.code, 'quantity_available': self.quantity_available, 'quantity_needed': self.quantity_needed, 'fulfilled': self.fulfilled, }