示例#1
0
class Role(PaginatedAPIMixin, db.Model):
    """角色表"""
    __tablename__ = 'roles'
    id = db.Column(db.Integer, primary_key=True)
    slug = db.Column(db.String(255), unique=True)
    name = db.Column(db.String(255))  # 角色表
    default = db.Column(db.Boolean, default=False, index=True)  # 是否是默认角色
    permissions = db.Column(
        db.Integer)  # 角色拥有的权限,各操作对应一个二进制位,能执行某项操作的角色,其位会被设为 1
    users = db.relationship('User', backref='role', lazy='dynamic')

    def __init__(self, **kwargs):
        super(Role, self).__init__(**kwargs)
        if self.permissions is None:
            self.permissions = 0

    @staticmethod
    def insert_roles():
        roles = {
            'shutup': ('小黑屋', ()),
            'reader': ('读者', (Permission.FOLLOW, Permission.COMMENT)),
            'author':
            ('作者', (Permission.FOLLOW, Permission.COMMENT, Permission.WRITE)),
            'administrator': ('管理员', (Permission.FOLLOW, Permission.COMMENT,
                                      Permission.WRITE, Permission.ADMIN))
        }
        default_role = 'reader'
        for r in roles:
            role = Role.query.filter_by(slug=r).first()
            if role is None:
                role = Role(slug=r, name=roles[r][0])
            role.reset_permission()
            for perm in roles[r][1]:
                role.add_permission(perm)
            role.default = (role.slug == default_role)
            db.session.add(role)
        db.session.commit()

    def reset_permission(self):
        """重置权限"""
        self.permissions = 0

    def has_permission(self, perm) -> bool:
        """是否存在此权限"""
        return self.permissions & perm == perm

    def add_permission(self, perm):
        """添加权限"""
        if not self.has_permission(perm):
            self.permissions += perm

    def remove_permission(self, perm):
        """删除权限"""
        if self.has_permission(perm):
            self.permissions -= perm

    def get_permissions(self):
        """获取角色具体权限操作"""
        p = [(Permission.FOLLOW, 'follow'),
             (Permission.ADMIN, 'administrator'), (Permission.WRITE, 'author'),
             (Permission.COMMENT, 'reader')]

        new_p = (i[1] for i in p if self.has_permission(i[0]))
        return ",".join(new_p)

    def to_dict(self):
        """序列化输出"""
        data = {
            'id': self.id,
            'slug': self.slug,
            'name': self.name,
            'default': self.default,
            'permissions': self.permissions,
            '_links': {
                'self': url_for('api.get_role', id=self.id)
            }
        }
        return data

    def from_dict(self, data):
        for field in ['slug', 'name', 'permissions']:
            if field in data:
                setattr(self, field, data[field])

    def __str__(self):
        return self.name

    def __repr__(self):
        return '<Role {}>'.format(self.name)
示例#2
0
class User(UserMixin, db.Model):
    __tablename__ ='users'
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    username = db.Column(db.String(32), nullable=False, unique=True)
    student_id = db.Column(db.Integer, nullable=False)
    true_name = db.Column(db.String(32), nullable=False)
    phone_number = db.Column(db.String(32), nullable=False)
    email = db.Column(db.String(64), nullable=False, unique=False)
    password_hash = db.Column(db.String(128), nullable=False)
    group_id = db.Column(db.Integer, db.ForeignKey('group.id'), default=2)
    group = db.relationship('Group', backref=db.backref('users', lazy='dynamic'))
    storage_id = db.Column(db.Integer, db.ForeignKey('store_location.id'), nullable=True)
    storage = db.relationship('Storage', backref=db.backref('users', lazy='dynamic'))
    last_login = db.Column(db.DateTime, default=datetime.now)
    icon = db.Column(db.String(64), default='img/a3.jpg')
    # Add a backreference to another model
    # Parameter 1: the associated model name
    # backref:Dynamically added fields in the associated model
    # Load mode: dynamic, no load, but provide record query
    # if use one to one,add uselist=Flase
    # posts = db.relationship('Post', backref='user', lazy=True)

    def __repr__(self):
        return self.username

    # Password field protection
    @property
    def password(self):
        raise AttributeError('keyword is Unreadable attribute')

    # Set the password and encrypt the storage
    @password.setter
    def password(self, password):
        #Equivalent to execution  user.password_hash=password
        self.password_hash = generate_password_hash(password)

    # Password check
    def verify_password(self, password):
        return check_password_hash(self.password_hash, password)
示例#3
0
class UserBindInfo(ModelBase):
    id = db.Column(db.Integer,
                   primary_key=True,
                   autoincrement=False,
                   comment='用户ID',
                   nullable=False)
    name = db.Column(db.String(64), comment="名称", nullable=False)
    account = db.Column(db.String(32),
                        comment="账号",
                        nullable=False,
                        index=True)
    _bind_type = db.Column('bind_type',
                           db.SmallInteger,
                           comment="绑定类型",
                           nullable=False)
    _merchant = db.Column('merchant',
                          db.Integer,
                          comment="商户ID",
                          nullable=False)

    __table_args__ = (
        # 联合唯一索引
        db.UniqueConstraint('name',
                            'bind_type',
                            'merchant',
                            name='uix_user_bind_name_bind_type_merchant'), )

    @property
    def uid(self):
        return self.id

    @uid.setter
    def uid(self, value):
        self.id = value

    @property
    def merchant(self) -> MerchantEnum:
        return MerchantEnum(self._merchant)

    @merchant.setter
    def merchant(self, merchant: MerchantEnum):
        self._merchant = merchant.value

    @property
    def bind_type(self):
        """
        返回账户枚举类型
        :return:
        """
        return AccountTypeEnum(self._bind_type)

    @bind_type.setter
    def bind_type(self, e_value):
        """
        传入账户的类型
        :param e_value:
        :return:
        """
        self._bind_type = e_value.value

    @classmethod
    def query_bind_by_uid(cls, uid):
        """
        根据用户ID查询绑定信息
        :param uid:
        :return:
        """
        return cls.query_one(query_fields=dict(id=uid))

    @classmethod
    def query_bind(cls,
                   merchant: MerchantEnum,
                   name,
                   bind_type: AccountTypeEnum = AccountTypeEnum.ACCOUNT):
        return cls.query_one(query_fields=dict(
            _merchant=merchant.value,
            name=name,
            _bind_type=bind_type.value,
        ))

    @classmethod
    def bind_account(cls,
                     uid,
                     merchant: MerchantEnum,
                     account,
                     name,
                     bind_type: AccountTypeEnum = AccountTypeEnum.ACCOUNT):
        obj = cls()
        obj.uid = uid
        obj.merchant = merchant
        obj.name = name
        obj.account = account
        obj.bind_type = bind_type
        cls.commit_models(obj)
        return obj

    @classmethod
    def unbind_account(cls, uid):
        obj = cls.query_bind_by_uid(uid)
        if not obj:
            return False
        cls.commit_models(obj, delete=True)
        return True
示例#4
0
class Despesas(db.Model):
    __tablename__ = 'Despesas'
    id = db.Column(db.INT(), primary_key=True)
    ano_mes_lancamento = db.Column(db.NVARCHAR(500))
    codigo_orgao_superior = db.Column(db.NVARCHAR(500))
    nome_orgao_superior = db.Column(db.NVARCHAR(500))
    codigo_orgao_subordinado = db.Column(db.NVARCHAR(500))
    nome_orgao_subordinado = db.Column(db.NVARCHAR(500))
    codigo_unidade_gestora = db.Column(db.NVARCHAR(500))
    nome_unidade_gestora = db.Column(db.NVARCHAR(500))
    codigo_gestao = db.Column(db.NVARCHAR(500))
    nome_gestao = db.Column(db.NVARCHAR(500))
    codigo_unidade_orcamentaria = db.Column(db.NVARCHAR(500))
    nome_unidade_orcamentaria = db.Column(db.NVARCHAR(500))
    codigo_funcao = db.Column(db.NVARCHAR(500))
    nome_funcao = db.Column(db.NVARCHAR(500))
    codigo_subfuncao = db.Column(db.NVARCHAR(500))
    nome_subfuncao = db.Column(db.NVARCHAR(500))
    codigo_programa_orcamentario = db.Column(db.NVARCHAR(500))
    nome_programa_orcamentario = db.Column(db.NVARCHAR(500))
    codigo_acao = db.Column(db.NVARCHAR(500))
    nome_acao = db.Column(db.NVARCHAR(500))
    idTipoDespesa = db.Column(db.NVARCHAR(500))
    idRubrica = db.Column(db.INT())
    idIes = db.Column(db.INT())
示例#5
0
class ActivityDetailBase(AuditMixin, Base):
    __tablename__ = 'activity_detail'

    activity_detail_id = db.Column(db.Integer,
                                   primary_key=True,
                                   server_default=FetchedValue())
    activity_type_description = db.Column(db.String)
    disturbed_area = db.Column(db.Numeric(14, 2))
    timber_volume = db.Column(db.Numeric(14, 2))
    number_of_sites = db.Column(db.Integer)
    width = db.Column(db.Integer)
    length = db.Column(db.Integer)
    depth = db.Column(db.Integer)
    quantity = db.Column(db.Integer)
    incline = db.Column(db.Numeric(14, 2))
    incline_unit_type_code = db.Column(
        db.String, db.ForeignKey('unit_type.unit_type_code'))
    cut_line_length = db.Column(db.Integer)
    water_quantity = db.Column(db.Integer)
    water_quantity_unit_type_code = db.Column(
        db.String, db.ForeignKey('unit_type.unit_type_code'))

    activity_summaries = db.relationship(
        'ActivitySummaryBase', secondary='activity_summary_detail_xref')
    activity_type_code = db.column_property(
        db.select([ActivitySummaryBase.activity_type_code],
                  and_(
                      ActivitySummaryDetailXref.activity_summary_id ==
                      ActivitySummaryBase.activity_summary_id,
                      ActivitySummaryDetailXref.activity_detail_id ==
                      activity_detail_id)).as_scalar())

    __mapper_args__ = {'polymorphic_on': activity_type_code}
示例#6
0
文件: user.py 项目: produvia/kryptos
class UserExchangeAuth(db.Model):
    id = db.Column(db.Integer, nullable=False, unique=True, primary_key=True)
    exchange = db.Column(db.String(), nullable=False, unique=False)
    user_id = db.Column(db.Integer, db.ForeignKey("users.id"))
示例#7
0
class CircleTaskBlock(db.Model):
    """ This represents meta information about 1 block in the circle task. """
    __tablename__ = 'circletask_blocks'
    __table_args__ = {
        'comment':
        "This table holds in each row information about a block in the Circle Task study. "
        "Blocks can be associated with one another as belonging to the same session. "
        "A session is a single run through the study with all its consecutive blocks. "
        "Each block is comprised of trials."
    }

    # The combination of user_id and hash should* be unique and could be used as a composite key (and drop id).
    # time column can't be used, as it may not be unique, even though it's unlikely.
    # *It's highly unlikely that someone produces the exact same dataset, but not impossible.
    id = db.Column(db.Integer,
                   primary_key=True,
                   comment="Unique identifier for a block.")
    user_id = db.Column(db.String(32),
                        db.ForeignKey('users.id'),
                        nullable=False,
                        comment="User who performed the task.")
    session_uid = db.Column(
        db.String(32),
        unique=False,
        nullable=False,
        comment=
        "The session a block belongs to. Sessions consist of consecutive blocks in a "
        "single run through the study.")
    nth_session = db.Column(
        db.Integer,
        unique=False,
        nullable=False,
        default=1,
        comment=
        "Chronological order of a session per user. How many times did a user upload data?"
    )
    nth_block = db.Column(
        db.Integer,
        unique=False,
        nullable=True,
        default=1,
        comment="Chronological order of a block within a session.")
    treatment = db.Column(
        db.String(120),
        unique=False,
        nullable=True,
        comment=
        "Which degree of freedom had a constraint on it during a block. Independent variable."
    )
    warm_up = db.Column(
        db.Float,
        unique=False,
        nullable=False,
        default=0.5,
        comment="Time before each trial to prepare, in seconds.")
    trial_duration = db.Column(
        db.Float,
        unique=False,
        nullable=False,
        default=2.0,
        comment="Time given for performing the task for each trial, in seconds."
    )
    cool_down = db.Column(
        db.Float,
        unique=False,
        nullable=False,
        default=0.5,
        comment="Time after each trial to give feedback, in seconds.")
    time = db.Column(
        db.Float,
        unique=False,
        nullable=True,
        comment="Time at which a block was finished, in seconds since epoch.")
    time_iso = db.Column(
        db.DateTime,
        unique=False,
        nullable=False,
        default=datetime.utcnow,
        comment="Time at which a block was finished, in ISO format.")
    rating = db.Column(
        db.Integer,
        unique=False,
        nullable=True,
        comment=
        "The user's perceived difficulty of the block on a Likert Scale. "
        "Very easy - 0,  Easy - 1,  Neutral - 2, Difficult - 3, Very difficult - 4"
    )
    hash = db.Column(
        db.String(32),
        unique=True,
        nullable=False,
        comment=
        "MD5 hash value for all the trials of a block. Used to check integrity of submitted data."
    )

    trials = db.relationship('CircleTaskTrial', backref='block')

    def __repr__(self):
        return f"CircleTaskBlock(user_id='{self.user_id}', session_uid={self.session_uid}, " \
               f"nth_session={self.nth_session}, nth_block={self.nth_block}, treatment='{self.treatment}', "\
               f"time={self.time}, time_iso='{self.time_iso}', rating='{self.rating}', hash='{self.hash}')"
示例#8
0
class User(UserMixin, db.Model):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(20), unique=True)
    password_hash = db.Column(db.String(128))
    email = db.Column(db.String(64), unique=True)
    confirmed = db.Column(db.Boolean, default=False)
    # 头像
    icon = db.Column(db.String(40), default='default.jpg')

    # 添加博客的反向引用
    posts = db.relationship('Posts', backref='user', lazy='dynamic')
    # 添加收藏的反向引用
    favorites = db.relationship('Posts',
                                secondary='collections',
                                backref=db.backref('users', lazy='dynamic'),
                                lazy='dynamic')

    @property
    def password(self):
        raise AttributeError('不能访问密码属性')

    @password.setter
    def password(self, password):
        self.password_hash = generate_password_hash(password)

    # 密码校验
    def vierify_password(self, password):
        return check_password_hash(self.password_hash, password)

    # 封装方法生成用于账户激活的token
    def generate_activate_token(self, expires_in=3600):
        s = Serializer(current_app.config['SECRET_KEY'], expires_in=expires_in)
        return s.dumps({'id': self.id})

    # 校验激活的token
    @staticmethod
    def check_activate_token(token):
        s = Serializer(current_app.config['SECRET_KEY'])
        try:
            data = s.loads(token)  # 判断是否有token这个值
        except:
            return False
        u = User.query.get(data['id'])
        if not u:
            return False
        # 如果用户没有激活
        if not u.confirmed:
            u.confirmed = True
            db.session.add(u)
        return True

    # 校验找回密码的token
    @staticmethod
    def check_find_token(token):
        s = Serializer(current_app.config['SECRET_KEY'])
        try:
            data = s.loads(token)  # 判断是否有token这个值
        except:
            return False
        u = User.query.get(data['id'])
        if u:
            return u

    # 封装修改邮箱的方法
    # 封装方法生成用于账户激活的token
    def generate_email_token(self, email, expires_in=3600):
        self.email = email
        s = Serializer(current_app.config['SECRET_KEY'], expires_in=expires_in)
        return s.dumps({'id': self.id, 'email': self.email})

    # 校验新邮箱
    @staticmethod
    def check_email_token(token):
        s = Serializer(current_app.config['SECRET_KEY'])
        try:
            data = s.loads(token)  # 判断是否有token这个值
        except:
            return False
        u = User.query.get(data['id'])
        if not u:
            return False
        # 如果用户没有激活
        if u:
            u.email = data['email']
            db.session.add(u)
        return True

    # 判断用户是否收藏指定模型
    def is_favorite(self, pid):
        # 所有收藏的博客
        favorite = self.favorites.filter(Posts.id == pid).first()
        if favorite:
            return True
        else:
            return False

    # 添加收藏
    def add_favorite(self, pid):
        p = Posts.query.get(pid)
        # favorite = self.favorites.all()
        # favorite.append(p)
        self.favorites.append(p)

    # 删除收藏
    def del_favorite(self, pid):
        p = Posts.query.get(pid)
        favorite = self.favorites.all()
        favorite.remove(p)
示例#9
0
class User(db.Model):

    __tablename__ = 'users'

    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(32), nullable=False, unique=True)
    email = db.Column(db.String(255), unique=True)
    activation_key = db.Column(db.String(36))
    created_time = db.Column(db.DateTime, default=get_current_time)

    # ================================================================
    # Password

    _password = db.Column('password', db.String(20), nullable=False)

    def _get_password(self):
        return self._password

    def _set_password(self, password):
        self._password = sha256_crypt.encrypt(password, rounds=12345)

    # Hide password encryption by exposing password field only.
    password = db.synonym('_password',
                          descriptor=property(_get_password, _set_password))

    def check_password(self, password):
        if self._password is None:
            return False
        return sha256_crypt.verify(password, self._password)

    # ================================================================
    # One-to-many relationship between users and roles.
    role_id = db.Column(db.SmallInteger, default=USER)

    def get_role(self):
        return USER_ROLE[self.role_id]

    # ================================================================
    # One-to-many relationship between users and user_statuses.
    status_id = db.Column(db.SmallInteger, default=INACTIVE)

    def get_status(self):
        return USER_STATUS[self.status_id]

    # ================================================================
    # One-to-one (uselist=False) relationship between users and user_details.
    user_detail_id = db.Column(db.Integer, db.ForeignKey("user_details.id"))
    user_detail = db.relationship("UserDetail", uselist=False, backref="users")

    # ================================================================
    # Class methods

    @classmethod  # TODO: What does this do?
    def authenticate(cls, login, password):
        user = cls.query.filter(
            db.or_(User.username == login, User.email == login)).first()
        authenticated = user.check_password(password) if user else False

        return user, authenticated

    def __repr__(self):
        return '<User %r>' % (self.username)

    def get_dob(self):
        return self.user_detail.dob.isoformat(
        ) if self.user_detail.dob is not None else None

    def as_dict(self):
        return {
            "id": self.id,
            "username": self.username,
            "email": self.email,
            "created_time": format_date(self.created_time),
            "first_name": self.user_detail.first_name,
            "last_name": self.user_detail.last_name,
            "gender": self.user_detail.gender,
            "dob": self.get_dob(),
            "phone": self.user_detail.phone,
            "bio": self.user_detail.bio,
            "url": self.user_detail.url
        }

    def session_as_dict(self):
        is_authenticated = self.is_authenticated()
        if (is_authenticated):
            return {
                "id": self.id,
                "username": self.username,
                "email": self.email,
                "status": self.get_status(),
                "auth": is_authenticated
            }
        else:
            return {"auth": is_authenticated}

    # ================================================================
    # Required by Flask-Login

    def is_authenticated(self):
        # Should just return True unless the object represents a user that should not be allowed to authenticate for some reason
        return True

    def is_active(self):
        return True if self.status_id == ACTIVE else False

    def is_anonymous(self):
        # Should return True only for fake users that are not supposed to log in to the system.
        return False

    def get_id(self):
        return unicode(self.id)
示例#10
0
class Goods(db.Model, HasImagesMixin):
    __tablename__ = 'goods'
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(255))
示例#11
0
class StatusUpdate(Base):
    __tablename__ = "status_update"
    __table_args__ = { "schema": "now_submissions" }
    id = db.Column(db.Integer, primary_key=True)
    businessareanumber = db.Column(db.String)
    status = db.Column(db.String)
    statusupdatedate = db.Column(db.DateTime)
    processed = db.Column(db.String)
    processeddate = db.Column(db.DateTime)
    requeststatus = db.Column(db.String)
    requestmessage = db.Column(db.String)
    seqnum = db.Column(db.Integer)
    statusreason = db.Column(db.String)
    applicationtype = db.Column(db.String)

    def __repr__(self):
        return '<Client %r>' % self.clientid
示例#12
0
"""
    app.users.models.followers
    ~~~~~~~~~~~~~~~~~~~~~~~~~~

    Followers model.
"""
from datetime import datetime
from app.extensions import db

followers = db.Table(
    'followers', db.Column('follower_id', db.Integer,
                           db.ForeignKey('user.id')),
    db.Column('followed_id', db.Integer, db.ForeignKey('user.id')),
    db.Column('created', db.DateTime, default=datetime.utcnow))
示例#13
0
class User(db.Model, Timestamp):
    """
    User database model.
    """

    id = db.Column(db.Integer, primary_key=True) # pylint: disable=invalid-name
    username = db.Column(db.String(length=80), unique=True, nullable=False)
    password = db.Column(
        column_types.PasswordType(
            max_length=128,
            schemes=('bcrypt', )
        ),
        nullable=False
    )
    email = db.Column(db.String(length=120), unique=True, nullable=False)

    first_name = db.Column(db.String(length=30), default='', nullable=False)
    middle_name = db.Column(db.String(length=30), default='', nullable=False)
    last_name = db.Column(db.String(length=30), default='', nullable=False)

    class StaticRoles(enum.Enum):
        # pylint: disable=missing-docstring,unsubscriptable-object
        INTERNAL = (0x8000, "Internal")
        ADMIN = (0x4000, "Admin")
        REGULAR_USER = (0x2000, "Regular User")
        ACTIVE = (0x1000, "Active Account")

        @property
        def mask(self):
            return self.value[0]

        @property
        def title(self):
            return self.value[1]

    static_roles = db.Column(db.Integer, default=0, nullable=False)

    is_internal = _get_is_static_role_property('is_internal', StaticRoles.INTERNAL)
    is_admin = _get_is_static_role_property('is_admin', StaticRoles.ADMIN)
    is_regular_user = _get_is_static_role_property('is_regular_user', StaticRoles.REGULAR_USER)
    is_active = _get_is_static_role_property('is_active', StaticRoles.ACTIVE)

    def __repr__(self):
        return (
            "<{class_name}("
            "id={self.id}, "
            "username=\"{self.username}\", "
            "email=\"{self.email}\", "
            "is_internal={self.is_internal}, "
            "is_admin={self.is_admin}, "
            "is_regular_user={self.is_regular_user}, "
            "is_active={self.is_active}, "
            ")>".format(
                class_name=self.__class__.__name__,
                self=self
            )
        )

    def has_static_role(self, role):
        return (self.static_roles & role.mask) != 0

    def set_static_role(self, role):
        if self.has_static_role(role):
            return
        self.static_roles |= role.mask

    def unset_static_role(self, role):
        if not self.has_static_role(role):
            return
        self.static_roles ^= role.mask

    def check_owner(self, user):
        return self == user

    @property
    def is_authenticated(self):
        return True

    @property
    def is_anonymous(self):
        return False

    @classmethod
    def find_with_password(cls, username, password):
        """
        Args:
            username (str)
            password (str) - plain-text password

        Returns:
            user (User) - if there is a user with a specified username and
            password, None otherwise.
        """
        user = cls.query.filter_by(username=username).first()
        if not user:
            return None
        if user.password == password:
            return user
        return None
示例#14
0
文件: mine.py 项目: alaigov/mds
class Mine(AuditMixin, Base):
    __tablename__ = 'mine'
    mine_guid = db.Column(UUID(as_uuid=True), primary_key=True)
    mine_no = db.Column(db.String(10))
    mine_name = db.Column(db.String(60), nullable=False)
    mine_note = db.Column(db.String(300), default='')
    major_mine_ind = db.Column(db.Boolean, nullable=False, default=False)
    deleted_ind = db.Column(db.Boolean, nullable=False, default=True)
    mine_region = db.Column(db.String(2),
                            db.ForeignKey('mine_region_code.mine_region_code'))
    mine_region = db.Column(db.String(2),
                            db.ForeignKey('mine_region_code.mine_region_code'))
    # Relationships
    mineral_tenure_xref = db.relationship('MineralTenureXref',
                                          backref='mine',
                                          lazy='joined')
    mine_location = db.relationship(
        'MineLocation',
        backref='mine=',
        order_by='desc(MineLocation.update_timestamp)',
        lazy='joined')
    mine_permit = db.relationship('Permit',
                                  backref='mine',
                                  order_by='desc(Permit.issue_date)',
                                  lazy='joined')
    mine_status = db.relationship('MineStatus',
                                  backref='mine',
                                  order_by='desc(MineStatus.update_timestamp)',
                                  lazy='joined')
    mine_tailings_storage_facilities = db.relationship(
        'MineTailingsStorageFacility',
        backref='mine',
        order_by=
        'desc(MineTailingsStorageFacility.mine_tailings_storage_facility_name)',
        lazy='joined')
    mine_expected_documents = db.relationship(
        'MineExpectedDocument',
        primaryjoin=
        "and_(MineExpectedDocument.mine_guid == Mine.mine_guid, MineExpectedDocument.active_ind==True)",
        backref='mine',
        order_by='desc(MineExpectedDocument.due_date)',
        lazy='joined')
    mine_type = db.relationship('MineType',
                                backref='mine',
                                order_by='desc(MineType.update_timestamp)',
                                lazy='joined')

    def __repr__(self):
        return '<Mine %r>' % self.mine_guid

    def json(self):
        return {
            'guid':
            str(self.mine_guid),
            'mine_name':
            self.mine_name,
            'mine_no':
            self.mine_no,
            'mine_note':
            self.mine_note,
            'major_mine_ind':
            self.major_mine_ind,
            'region_code':
            self.mine_region,
            'mineral_tenure_xref':
            [item.json() for item in self.mineral_tenure_xref],
            'mine_location': [item.json() for item in self.mine_location],
            'mine_permit': [item.json() for item in self.mine_permit],
            'mine_status': [item.json() for item in self.mine_status],
            'mine_tailings_storage_facility':
            [item.json() for item in self.mine_tailings_storage_facilities],
            'mine_expected_documents':
            [item.json() for item in self.mine_expected_documents],
            'mine_type': [item.json() for item in self.active(self.mine_type)]
        }

    def json_for_list(self):
        return {
            'guid':
            str(self.mine_guid),
            'mine_name':
            self.mine_name,
            'mine_no':
            self.mine_no,
            'mine_note':
            self.mine_note,
            'major_mine_ind':
            self.major_mine_ind,
            'region_code':
            self.mine_region,
            'mine_permit': [item.json() for item in self.mine_permit],
            'mine_status': [item.json() for item in self.mine_status],
            'mine_tailings_storage_facility':
            [item.json() for item in self.mine_tailings_storage_facilities],
            'mine_type': [item.json() for item in self.active(self.mine_type)]
        }

    def json_for_map(self):
        return {
            'guid': str(self.mine_guid),
            'mine_name': self.mine_name,
            'mine_no': self.mine_no,
            'mine_note': self.mine_note,
            'major_mine_ind': self.major_mine_ind,
            'region_code': self.mine_region,
            'mine_location': [item.json() for item in self.mine_location]
        }

    def json_by_name(self):
        return {
            'guid': str(self.mine_guid),
            'mine_name': self.mine_name,
            'mine_no': self.mine_no
        }

    def json_by_location(self):
        mine_location = self.mine_location[0] if self.mine_location else None
        return {
            'guid': str(self.mine_guid),
            'latitude': str(mine_location.latitude) if mine_location else '',
            'longitude': str(mine_location.longitude) if mine_location else ''
        }

    def json_by_permit(self):
        return {
            'guid': str(self.mine_guid),
            'mine_permit': [item.json() for item in self.mine_permit]
        }

    @staticmethod
    def active(records):
        return list(filter(lambda x: x.active_ind, records))

    @classmethod
    def find_by_mine_guid(cls, _id):
        try:
            uuid.UUID(_id, version=4)
            return cls.query.filter_by(mine_guid=_id).first()
        except ValueError:
            return None

    @classmethod
    def find_by_mine_no(cls, _id):
        return cls.query.filter_by(mine_no=_id).first()

    @classmethod
    def find_by_mine_no_or_guid(cls, _id):
        result = cls.find_by_mine_guid(_id)
        if result is None:
            result = cls.find_by_mine_no(_id)

        return result

    @classmethod
    def create_mine(cls,
                    mine_no,
                    mine_name,
                    mine_category,
                    mine_region,
                    user_kwargs,
                    save=True):
        mine = cls(mine_guid=uuid.uuid4(),
                   mine_no=mine_no,
                   mine_name=mine_name,
                   major_mine_ind=mine_category,
                   mine_region=mine_region,
                   **user_kwargs)
        if save:
            mine.save(commit=False)
        return mine

    @validates('mine_name')
    def validate_mine_name(self, key, mine_name):
        if not mine_name:
            raise AssertionError('No mine name provided.')
        if len(mine_name) > 60:
            raise AssertionError('Mine name must not exceed 60 characters.')
        return mine_name

    @validates('mine_note')
    def validate_mine_note(self, key, mine_note):
        if len(mine_note) > 300:
            raise AssertionError('Mine note must not exceed 300 characters.')
        return mine_note

    @validates('mine_no')
    def validate_mine_no(self, key, mine_no):
        if len(mine_no) > 10:
            raise AssertionError('Mine number must not exceed 10 characters.')
        return mine_no
示例#15
0
class User(UserMixin, db.Model):
    __tablename__ = 'user'
    userid = db.Column(db.String(64), primary_key=True, default=str(uuid1()))
    username = db.Column(db.String(64), nullable=False)
    realname = db.Column(db.String(64), default='')
    mobile = db.Column(db.String(32), nullable=False)
    password_hash = db.Column(db.String(128), nullable=False)
    level = db.Column(db.String(2), default='1')
    score = db.Column(db.String(10), default='0')
    role = db.Column(db.String(2), default='1')
    email = db.Column(db.String(128), nullable=False)
    blackflag = db.Column(db.String(2), default='0')
    delflag = db.Column(db.String(2), default='0')
    createtime = db.Column(db.DateTime, default=str(datetime.now()))

    def db2json(self):
        data = to_json(self)
        return data

    @property
    def password(self):
        raise AttributeError('密码是不可读属性')

    @password.setter
    def password(self, password):
        self.password_hash = generate_password_hash(password)

    # 密码校验
    def verify_password(self, password):
        return check_password_hash(self.password_hash, password)

    # 生成token作为校验
    def encode_auth_token(self, user_id):
        try:
            payload = {
                'exp': datetime.utcnow() + timedelta(days=1, seconds=0),
                'iat': datetime.utcnow(),
                'sub': user_id
            }
            return jwt.encode(payload, Config.SECRET_KEY, algorithm='HS256')
        except Exception as e:
            return e

    # 对token解码
    # 用静态方法,使其与class实例无关
    @staticmethod
    def decode_auth_token(auth_token):
        try:
            payload = jwt.decode(auth_token, Config.SECRET_KEY)
            return payload['sub'], 200
        except jwt.ExpiredSignatureError:
            return '签名已过期,请再次登录', 401
        except jwt.InvalidTokenError:
            return '令牌无效,请再次登录', 403
示例#16
0
from .user import User
from .posts import Posts
from app.extensions import db

# 创建多对多的中间关联表,ORM自动维护
collections = db.Table(
    'collections', db.Column('user_id', db.Integer, db.ForeignKey('users.id')),
    db.Column('posts_id', db.Integer, db.ForeignKey('posts.id')))
示例#17
0
#-*-coding=utf-8-*-
# project:     workspace
# createtime:  2018/4/12  9:09
# IDE:         PyCharm
# anthor:      ZT@gufan

from app.extensions import db

#定义多对多关系 注意定义一个中间表
posts_tags = db.Table(
    "posts_tags", db.Column('post_id', db.Integer, db.ForeignKey("posts.id")),
    db.Column('tag_id', db.Integer, db.ForeignKey('tags.id')))


class User(db.Model):

    __tablename__ = "users"
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(255), nullable=False)
    password = db.Column(db.String(255), nullable=False)
    posts = db.relationship('Post', backref="users", lazy="dynamic")

    def __repr__(self):
        return "<Model User {}>".format(self.username)


class Post(db.Model):
    __tablename__ = "posts"
    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String(255))
    text = db.Column(db.Text())
示例#18
0
class Udcontent(db.Model):
    __tablename__ = 'udcontent'
    id = db.Column(db.Integer, primary_key=True)
    content = db.Column(db.String(32))
    ud_id = db.Column(db.Integer)
    pid = db.Column(db.Integer)
示例#19
0
文件: user.py 项目: produvia/kryptos
class StrategyModel(db.Model):
    __tablename__ = "strategies"

    id = db.Column(db.Integer, nullable=False, unique=True, primary_key=True)
    uuid = db.Column(db.String(), unique=True, default=shortuuid.uuid())
    name = db.Column(db.String(), nullable=False, unique=False)
    created_at = db.Column(db.DateTime(), default=datetime.datetime.now())
    trading_config = db.Column(db.JSON(), nullable=False, unique=False)
    dataset_config = db.Column(db.JSON(), nullable=False, unique=False)
    indicators_config = db.Column(db.JSON(), nullable=False, unique=False)
    signals_config = db.Column(db.JSON(), nullable=False, unique=False)

    status = db.Column(db.String(),
                       nullable=True,
                       unique=False,
                       primary_key=False)

    result_json = db.Column(db.JSON(), nullable=True, unique=False)

    user_id = db.Column(db.Integer, db.ForeignKey("users.id"))

    @classmethod
    def from_json(cls, strat_json, user_id=None):
        d = json.loads(strat_json)
        instance = cls()

        instance.uuid = shortuuid.uuid()
        instance.name = d.get("name")
        instance.trading_config = d.get("trading")
        instance.dataset_config = d.get("datasets")
        instance.indicators_config = d.get("indicators")
        instance.signals_config = d.get("signals")

        if user_id is not None:
            instance.user_id = user_id

        return instance

    def update_from_job(self, job):
        self.status = job.status
        current_app.logger.debug(
            f"Updating strategy {self.id} status: {self.status}")
        if job.result:
            current_app.logger.debug(f"Strategy {self.id} job has finished")
            self.result_json = job.result

        db.session.commit()

    def config_to_json(self):
        d = {
            "id": self.id,
            "name": self.name,
            "trading": self.trading_config,
            "datasets": self.dataset_config,
            "indicator": self.indicators_config,
            "signals_config": self.signals_config,
        }
        return json.dumps(d)

    @property
    def parsed_result_json(self):
        if self.result_json is None:
            return {}
        d = json.loads(self.result_json)
        clean_result = {}
        for k, v in d.items():
            # nested dict with trading type as key
            metric, val = k, v.get("Backtest", v)
            clean_result[metric] = val
        return clean_result

    def pretty_result(self):
        string = ""
        if self.result_json is None:
            return None
        result_dict = json.loads(self.result_json)
        for k, v in result_dict.items():
            # nested dict with trading type as key
            metric, val = k, v["Backtest"]
            string += f"{metric}: {val}\n"
        return string
示例#20
0
class Application(Base, AuditMixin):
    __tablename__ = 'application'

    class _ModelSchema(Base._ModelSchema):
        id = fields.Integer(dump_only=True)
        guid = fields.String(dump_only=True)
        submission_date = fields.String(dump_only=True)
        status_changes = fields.Raw(dump_only=True)  ##DO NOT INGEST ON POST

    id = db.Column(db.Integer, primary_key=True, server_default=FetchedValue())
    guid = db.Column(UUID(as_uuid=True),
                     nullable=False,
                     unique=True,
                     server_default=FetchedValue())

    submission_date = db.Column(db.DateTime,
                                nullable=False,
                                default=datetime.utcnow)
    json = db.Column(JSONB, nullable=False)
    review_json = db.Column(JSONB)
    submitter_ip = db.Column(db.String)
    edit_note = db.Column(db.String)
    application_phase_code = db.Column(
        db.String,
        db.ForeignKey('application_phase_type.application_phase_code'),
        nullable=False)

    documents = db.relationship('ApplicationDocument', lazy='select')
    payment_documents = db.relationship(
        'PaymentDocument',
        lazy='select',
        primaryjoin=
        'and_(PaymentDocument.application_guid == Application.guid, PaymentDocument.active_ind == True)'
    )

    status_changes = db.relationship(
        'ApplicationStatusChange',
        lazy='select',
        order_by='desc(ApplicationStatusChange.change_date)',
    )

    def __repr__(self):
        return f'<{self.__class__.__name__} {self.guid}>'

    @classmethod
    def get_all(cls):
        return cls.query.all()

    @classmethod
    def find_by_guid(cls, guid):
        return cls.query.filter_by(guid=guid).one_or_none()

    @validates('json')
    def validate_json(self, key, json):
        well_sites = json.get('well_sites')
        for site in well_sites:
            contracted_work = site.get('contracted_work')
            work = list(
                set(list(WELL_SITE_CONTRACTED_WORK.keys())).intersection(
                    contracted_work))
            if len(work) == 0:
                raise AssertionError(
                    'Application must contain at least one piece of contracted work.'
                )
            for i in work:
                work_item = contracted_work.get(i)
                total = [
                    value for key, value in work_item.items()
                    if key in WELL_SITE_CONTRACTED_WORK.get(i)
                ]
                if sum(total) == 0:
                    raise AssertionError(
                        'Contracted works must have an amount greater than $0')
        for key, value in APPLICATION_JSON.items():
            k = json.get(key, None)
            if k:
                for item in value:
                    if item == 'company_name':
                        company_name = k.get(item, None)
                        if company_name:
                            for i in COMPANY_NAME_JSON_KEYS:
                                if not company_name.get(i, None):
                                    raise AssertionError(
                                        f'{i} must not be None')
                        else:
                            raise AssertionError(f'{item} must not be None')
                    if not k.get(item, None):
                        raise AssertionError(f'{item} must not be None')
            else:
                raise AssertionError(f'{key} must not be None')

        return json

    @hybrid_property
    def company_name(self):
        return self.json.get('company_details', {}).get('company_name',
                                                        {}).get('label')

    @company_name.expression
    def company_name(self):
        return Application.json['company_details']['company_name'][
            'label'].astext

    @hybrid_property
    def agreement_number(self):
        return str(self.id).zfill(4)

    @hybrid_property
    def well_sites_with_review_data(self):
        """Merges well sites with their corresponding review data and provides extra information."""

        well_sites = self.json.get('well_sites')

        # Merge well sites with their corresponding review data.
        if self.review_json:
            ws_reviews = self.review_json.get('well_sites')
            for i, ws_review in enumerate(ws_reviews):
                if not ws_review:
                    continue
                for wan, review_data in ws_review.items():
                    for k, v in review_data.items():
                        if k != 'contracted_work':
                            continue
                        for cw_type, cw_data in v.items():
                            well_sites[i]['contracted_work'][cw_type].update(
                                cw_data)

        # Calculate the sum for each contracted work item
        for i, well_site in enumerate(well_sites):
            for cw_type, cw_data in well_site.get('contracted_work',
                                                  {}).items():
                cw_total = 0
                for k, v in cw_data.items():
                    if k in WELL_SITE_CONTRACTED_WORK[cw_type]:
                        cw_total += v
                well_sites[i]['contracted_work'][cw_type][
                    'contracted_work_total'] = round(cw_total, 2)

        return well_sites

    @hybrid_method
    def contracted_work(self, status, include_payment):
        contracted_work = []
        contracted_work_payments = None
        if include_payment:
            contracted_work_payments = marshal(
                ContractedWorkPayment.find_by_application_guid(self.guid),
                CONTRACTED_WORK_PAYMENT)
        for ws in self.well_sites_with_review_data:
            for cw_type, cw_data in ws.get('contracted_work', {}).items():
                if cw_data.get('contracted_work_status_code', None) != status:
                    continue
                cw_item = {}
                cw_item['application_id'] = self.id
                cw_item['application_guid'] = str(self.guid)
                cw_item['company_name'] = self.company_name
                cw_item['contracted_work_type'] = cw_type
                cw_item['well_authorization_number'] = ws['details'][
                    'well_authorization_number']
                cw_item['estimated_shared_cost'] = self.calc_est_shared_cost(
                    cw_data)
                cw_item.update(cw_data)
                if include_payment:
                    cw_payment = next(
                        (cwp for cwp in contracted_work_payments
                         if cwp['work_id'] == cw_item['work_id']), None)
                    cw_item['contracted_work_payment'] = cw_payment
                contracted_work.append(cw_item)

        return contracted_work

    @classmethod
    def all_approved_contracted_work(self,
                                     application_id=None,
                                     application_guid=None,
                                     company_name=None):
        contracted_work_payments = []
        approved_applications = []

        if application_id or application_guid or company_name:
            if application_id and not application_guid:
                application = Application.query.filter_by(
                    id=application_id).one_or_none()
                application_guid = application.guid if application else None
            approved_applications = Application.query.filter(
                and_(
                    Application.application_status_code ==
                    'FIRST_PAY_APPROVED', Application.id == application_id
                    if application_id != None else True, Application.guid
                    == application_guid if application_guid != None else True,
                    Application.company_name == company_name
                    if company_name != None else True)).order_by(
                        Application.id).all()
            approved_application_guids = [
                x.guid for x in approved_applications
            ]
            contracted_work_payments = ContractedWorkPayment.query.filter(
                Application.guid.in_(approved_application_guids)).all()
        else:
            approved_applications = Application.query.filter_by(
                application_status_code='FIRST_PAY_APPROVED').order_by(
                    Application.id).all()
            contracted_work_payments = ContractedWorkPayment.query.all()

        contracted_work_payments_lookup = {}
        for cwp in contracted_work_payments:
            contracted_work_payments_lookup[cwp.work_id] = marshal(
                cwp, CONTRACTED_WORK_PAYMENT)

        approved_applications_approved_contracted_work = []
        for application in approved_applications:
            for approved_work in application.contracted_work(
                    'APPROVED', False):
                approved_work[
                    'contracted_work_payment'] = contracted_work_payments_lookup.get(
                        approved_work['work_id'], None)
                approved_work[
                    'application_phase_code'] = application.application_phase_code
                approved_applications_approved_contracted_work.append(
                    approved_work)
        return approved_applications_approved_contracted_work

    def find_contracted_work_by_id(self, work_id):
        for ws in self.well_sites_with_review_data:
            for cw_type, cw_data in ws.get('contracted_work', {}).items():
                if cw_data['work_id'] == work_id:
                    return cw_data

    def find_contracted_work_type_by_work_id(self, work_id):
        for ws in self.well_sites_with_review_data:
            for cw_type, cw_data in ws.get('contracted_work', {}).items():
                if cw_data['work_id'] == work_id:
                    return cw_type

    def calc_est_shared_cost(self, contracted_work):
        """Calculates the contracted work item's Estimated Shared Cost, which is half of the estimated cost \
            unless that value is $100,000 or more, then it is $100,000.
        """

        half_est_cost = round(contracted_work['contracted_work_total'] / 2.0,
                              2)
        est_shared_cost = half_est_cost if half_est_cost <= 100000 else 100000
        return est_shared_cost

    def calc_total_est_shared_cost(self):
        """Calculates this application's contribution (sum of all contracted work Estimated Shared Cost) to the Provincial Financial Contribution total."""

        total_est_shared_cost = 0
        for ws in self.well_sites_with_review_data:
            for cw_type, cw_data in ws.get('contracted_work', {}).items():
                if cw_data.get('contracted_work_status_code',
                               None) != 'APPROVED':
                    continue
                total_est_shared_cost += self.calc_est_shared_cost(cw_data)
        return total_est_shared_cost

    def calc_first_prf_amount(self):
        """Calculates this application's payment phase one amount, which is 10% of the total estimated shared cost."""

        return round(self.calc_total_est_shared_cost() * 0.10, 2)

    @hybrid_property
    def shared_cost_agreement_template_json(self):
        """Generates the JSON used to generate this application's Shared Cost Agreement document."""

        result = self.json

        # Create general document info
        result['agreement_no'] = self.agreement_number
        result['application_guid'] = str(self.guid)
        result['agreement_date'] = datetime.now().strftime("%d, %b, %Y")

        # Create company info
        _company_details = self.json.get('company_details')
        _company_name = _company_details['company_name']['label']
        addr1 = _company_details.get('address_line_1')
        addr2 = _company_details.get(
            'address_line_2') + '\n' if _company_details.get(
                'address_line_2') else ""
        city = _company_details.get('city')
        post_cd = _company_details.get('postal_code')
        prov = _company_details.get('province')

        # Create applicant info
        _applicant_name = self.applicant_name
        result['applicant_name'] = _applicant_name
        result[
            'applicant_address'] = f'{addr1}\n{addr2}{post_cd}\n{city}, {prov}'
        result['applicant_company_name'] = _company_name
        result['funding_amount'] = '${:,.2f}'.format(
            self.calc_total_est_shared_cost())
        result[
            'recipient_contact_details'] = f'{_applicant_name},\n{_company_name},\n{addr1} {post_cd} {city} {prov},\n{self.applicant_email},\n{self.submitter_phone_1}'

        # Create detailed info for each well site's contracted work items
        result['formatted_well_sites'] = ""
        for ws in self.well_sites_with_review_data:
            site_details = ws.get('details', {})
            wan = site_details.get('well_authorization_number')
            for worktype, wt_details in ws.get('contracted_work', {}).items():
                if wt_details.get('contracted_work_status_code',
                                  None) != 'APPROVED':
                    continue
                site = f'\nWell Authorization Number: {wan}\n'
                site += f' Eligible Activities as described in Application: {worktype.replace("_"," ").capitalize()}\n'
                site += f' Applicant\'s Estimated Cost: {"${:,.2f}".format(wt_details.get("contracted_work_total"))}\n'
                site += f' Provincial Financial Contribution: {"${:,.2f}".format(self.calc_est_shared_cost(wt_details))}\n'
                site += f' Planned Start Date: {wt_details["planned_start_date"]}\n'
                site += f' Planned End Date: {wt_details["planned_end_date"]}\n'
                result['formatted_well_sites'] += site

        return result

    @hybrid_property
    def applicant_name(self):
        return f"{self.json['company_contact']['first_name']} {self.json['company_contact']['last_name']}"

    @hybrid_property
    def applicant_email(self):
        return self.json.get('company_contact', {}).get('email')

    @hybrid_property
    def submitter_phone_1(self):
        ph1 = self.json.get('company_contact', {}).get('phone_number_1')
        ph1_ext = self.json.get('company_contact',
                                {}).get('phone_number_1_ext')

        return ph1 if not ph1_ext else f'{ph1} ext.{ph1_ext}'

    @hybrid_property
    def application_status_code(self):
        if self.status_changes:
            return self.status_changes[0].application_status_code
        else:
            return 'NOT_STARTED'

    @application_status_code.expression
    def application_status_code(self):
        return func.coalesce(
            select([ApplicationStatusChange.application_status_code]).where(
                ApplicationStatusChange.application_guid ==
                self.guid).order_by(desc(
                    ApplicationStatusChange.change_date)).limit(1).as_scalar(),
            'NOT_STARTED')

    def send_confirmation_email(self):
        html_content = f"""
            <p>
                We have successfully received your application in the British Columbia Dormant Sites Reclamation Program.
                Please keep your reference number safe as you will need it to carry your application forward in this process.
                You can view the contents of your application below.
                <br />
                <br />
                <a href='{Config.URL}/view-application-status/{self.guid}'>Click here to view the status of your application.</a>
                <br/>
                <br/>
                <br/>
                <br/>
                <br/>
            </p>
            {self.get_application_html()}
            """
        with EmailService() as es:
            es.send_email_to_applicant(self, 'Application Confirmation',
                                       html_content)

    def get_application_html(self):
        def create_company_details(company_details):
            indigenous_content = ''
            if self.application_phase_code == 'INITIAL':
                indigenous_participation_ind = company_details.get(
                    'indigenous_participation_ind', False) == True
                indigenous_content = f"""
                <h2>Indigenous Participation</h2>
                <p>{"Yes" if indigenous_participation_ind else "No"}</p>
                {f'<p>{company_details["indigenous_participation_description"]}</p>' if indigenous_participation_ind else ""}
                """
            elif self.application_phase_code == 'NOMINATION':
                indigenous_affiliation = company_details.get(
                    'indigenous_affiliation')
                indigenous_communities = company_details.get(
                    'indigenous_communities', [])
                has_indigenous_affiliation = indigenous_affiliation and indigenous_communities and indigenous_affiliation != 'NONE' and indigenous_affiliation in INDIGENOUS_APPLICANT_AFFILIATION
                indigenous_affiliation_label = INDIGENOUS_APPLICANT_AFFILIATION[
                    indigenous_affiliation] if has_indigenous_affiliation else INDIGENOUS_APPLICANT_AFFILIATION[
                        "NONE"]

                indigenous_content = f"""
                <h2>Indigenous Affiliation</h2>
                <p>{indigenous_affiliation_label}</p>
                """

                if has_indigenous_affiliation:

                    def create_indigenous_community(community):
                        return f'<li>{community}</li>'

                    indigenous_content += f"""
                    <h3>Indigenous Peoples</h3>
                    <ul>
                    {''.join([create_indigenous_community(community) for community in indigenous_communities])}
                    </ul>
                    """

            return f"""
            <h1>Company Details</h1>

            <h2>Company Name</h2>
            <p>{company_details["company_name"]["label"]}</p>

            <h2>Company Address</h2>
            <p>
            {company_details["city"]} {company_details["province"]} Canada
            <br />
            {company_details["address_line_1"]}
            <br />
            {f'{company_details["address_line_2"]}<br />' if company_details.get("address_line_2") else ""}
            {company_details["postal_code"]}
            </p>

            <h2>Business Number</h2>
            <p>{company_details["business_number"]}</p>

            {indigenous_content}
            """

        def create_company_contact(company_contact):
            return f"""
            <h1>Company Contact</h1>

            <p>{company_contact["first_name"]} {company_contact["last_name"]}</p>
            <p>{company_contact["email"]}</p>
            <p>
            Phone: {company_contact["phone_number_1"]}<br />     
            {f'Ext.: {company_contact["phone_ext_1"]}<br />' if company_contact.get("phone_ext_1") else ""} 
            {f'Phone 2.: {company_contact["phone_number_2"]}<br />' if company_contact.get("phone_number_2") else ""}
            {f'Ext. 2: {company_contact["phone_ext_2"]}<br />' if company_contact.get("phone_ext_2") else ""}
            {f'Fax: {company_contact["fax"]}<br />' if company_contact.get("fax") else ""}
            </p>
            """

        def create_contract_details(contract_details):
            try:
                permit_holder = PermitHolderResource.get(
                    self,
                    operator_id=contract_details["operator_id"])["records"][0]
            except:
                current_app.logger.warning(
                    'Failed to find the permit holder. Displaying operator ID instead.'
                )

            return f"""
            <h1>Contract Details</h1>

            <h2>Permit Holder</h2>
            <p>{permit_holder["organization_name"] if permit_holder else f'Operator ID: {contract_details["operator_id"]}'}</p>
            """

        def create_well_sites(well_sites):
            def create_well_site(well_site, index):
                def create_site_condition(condition, site_conditions):
                    return f"<li><b>{condition['label']}</b>: {'Yes' if condition['name'] in site_conditions and site_conditions[condition['name']] == True else 'No'}</li>"

                def create_contracted_work_section(section, contracted_work):
                    def create_indigenous_subcontractors(
                            section, contracted_work):
                        if self.application_phase_code == 'INITIAL':
                            return ''

                        def create_indigenous_subcontractor(
                                number, subcontractor):
                            return f"""
                            Subcontractor {number}:<br />
                            <p>
                            Subcontractor Name: {subcontractor['indigenous_subcontractor_name']}<br />
                            Indigenous Affiliation: {INDIGENOUS_SUBCONTRACTOR_AFFILIATION[subcontractor['indigenous_affiliation']]}<br />
                            Indigenous Peoples:<br />
                            <ul>
                            {''.join([f'<li>{community}</li>' for community in subcontractor['indigenous_communities']])}
                            </ul>
                            </p>
                            """

                        indigenous_subcontractors = contracted_work.get(
                            section['section_name'],
                            {}).get('indigenous_subcontractors', [])
                        indigenous_subcontractors_content = 'N/A' if not indigenous_subcontractors else ''.join(
                            [
                                create_indigenous_subcontractor(
                                    i + 1, subcontractor) for i, subcontractor
                                in enumerate(indigenous_subcontractors)
                            ])
                        return f"""
                        <p><u>Indigenous Subcontractors</u></p>
                        {indigenous_subcontractors_content}
                        """

                    def create_sub_section(sub_section, section,
                                           contracted_work):
                        def create_amount_field(amount_field, section,
                                                contracted_work):
                            return f"""
                                <tr>
                                <td style="padding-left: 10px;">{amount_field["label"]}:</td>
                                <td style="padding-left: 10px;">{'$0.00' if not (section["section_name"] in contracted_work and (amount_field["name"] in contracted_work[section["section_name"]])) else f'${contracted_work[section["section_name"]][amount_field["name"]] or "0.00"}'}</td>
                                </tr>
                            """

                        return f"""
                        <p><u>{sub_section["sub_section_header"]}</u></p>
                        <table class="contracted_work_amount">
                        {''.join([create_amount_field(amount_field, section, contracted_work) for amount_field in sub_section["amount_fields"]])}
                        </table>
                        """

                    return f"""             
                    <h4>{section["section_header"]}</h4>
                    <p>Planned Start Date: {contracted_work[section["section_name"]]["planned_start_date"] if contracted_work.get(section["section_name"]) and contracted_work.get(section["section_name"]).get("planned_start_date") else "N/A"}</p>
                    <p>Planned End Date: {contracted_work[section["section_name"]]["planned_end_date"] if contracted_work.get(section["section_name"]) and contracted_work.get(section["section_name"]).get("planned_end_date") else "N/A"}</p>
                    {''.join([create_sub_section(sub_section, section, contracted_work) for sub_section in section["sub_sections"]])}
                    <br />
                    {create_indigenous_subcontractors(section, contracted_work)}
                    """

                def create_site_condition(site_conditions):
                    site_conditions_section = "" if self.application_phase_code == 'NOMINATION' else f"""
                    h3>Site Conditions</h3>
                    {''.join()}
                    <ul>
                    {''.join([create_site_condition(condition, well_site["site_conditions"]) for condition in SITE_CONDITIONS])}
                    </ul>
                    """

                return f"""
                <h2>Well Site {index + 1}</h2>

                <h3>Well Authorization Number</h3>
                <p>{well_site["details"]["well_authorization_number"]}</p>

                {create_site_condition(well_site)}

                <h3>Contracted Work</h3>
                {''.join([create_contracted_work_section(section, well_site["contracted_work"]) for section in CONTRACTED_WORK])}
                <hr />
                """

            return f"""
            <h1>Well Sites</h1>
            {''.join([create_well_site(well_site, index) for index, well_site in enumerate(well_sites)])}
            """

        html = f"""
        {create_company_details(self.json["company_details"])}     
        {create_company_contact(self.json["company_contact"])}
        {create_contract_details(self.json["contract_details"])}
        {create_well_sites(self.json["well_sites"])}
        """

        return html

    def save_application_history(self):
        application_json = marshal(self, APPLICATION)
        application_json["application_id"] = self.id
        application_history = ApplicationHistory._schema().load(
            application_json)
        application_history.save()
        return application_history

    def process_well_sites_work_items(self, well_sites_json, func, **args):
        def perform(self, fun, **args):
            fun(**args)

        for site in well_sites_json:
            contracted_work = site.get('contracted_work')
            works = list(
                set(list(WELL_SITE_CONTRACTED_WORK.keys())).intersection(
                    contracted_work))
            for i in works:
                work_item = contracted_work.get(i)
                if args is not None:
                    args["work_item"] = work_item

                perform(self, func, **args)

    def update_work_item_action(self, work_item, id, planned_start_date,
                                planned_end_date):
        if work_item["work_id"] == id:
            work_item["planned_start_date"] = planned_start_date
            work_item["planned_end_date"] = planned_end_date

    def iterate_application_work_items_action(self, work_item):
        application_json = marshal(self, APPLICATION)
        json = application_json["json"]["well_sites"]
        args = {
            "id": work_item["work_id"],
            "planned_start_date": work_item["planned_start_date"],
            "planned_end_date": work_item["planned_end_date"]
        }
        self.process_well_sites_work_items(json, self.update_work_item_action,
                                           **args)
示例#21
0
class CircleTaskTrial(db.Model):
    """ Variables specific to circle task. """
    __tablename__ = 'circletask_trials'
    __table_args__ = {
        'comment':
        "This table holds in each row information about the outcome of a single trial from "
        "the Circle Task study. Trials belong to a block, which are part of a complete run "
        "through the study."
    }

    # Can't use ForeignKeyConstraint as composite key,
    # because user_id, session and block are not unique keys in reference table.
    id = db.Column(db.Integer,
                   primary_key=True,
                   comment="Unique identifier of a trial.")
    # ToDo: user_id rly necessary? -> self.block_id.user_id or get-method
    user_id = db.Column(db.String(32),
                        db.ForeignKey('users.id'),
                        nullable=False,
                        comment="User who performed the task.")
    block_id = db.Column(db.Integer,
                         db.ForeignKey('circletask_blocks.id'),
                         nullable=False,
                         comment="The block a trial belongs to.")
    # Since nth_block is a non-unique property in CircleTaskBlock we cannot place its value here,
    # but have to go through block_id.
    trial = db.Column(db.Integer,
                      unique=False,
                      nullable=False,
                      comment="Chronological order of trial within a block.")
    df1 = db.Column(
        db.Float,
        unique=False,
        nullable=True,
        comment=
        "Value of degree of freedom 1 at end of trial. Dependent variable.")
    df2 = db.Column(
        db.Float,
        unique=False,
        nullable=True,
        comment=
        "Value of degree of freedom 2 at end of trial. Dependent variable.")
    df1_grab = db.Column(
        db.Float,
        unique=False,
        nullable=True,
        comment=
        "Delta time in seconds after trial onset at which df1 slider was grabbed."
    )
    df1_release = db.Column(
        db.Float,
        unique=False,
        nullable=True,
        comment=
        "Delta time in seconds after trial onset at which df1 slider was released, either "
        "by the user or by the end of the countdown.")
    df1_duration = db.Column(db.Float,
                             unique=False,
                             nullable=True,
                             comment="Duration of the df1 grab, in seconds.")
    df2_grab = db.Column(
        db.Float,
        unique=False,
        nullable=True,
        comment=
        "Delta time in seconds after trial onset at which df2 slider was grabbed."
    )
    df2_release = db.Column(
        db.Float,
        unique=False,
        nullable=True,
        comment=
        "Delta time in seconds after trial onset at which df2 slider was released, either "
        "by the user or by the end of the countdown.")
    df2_duration = db.Column(db.Float,
                             unique=False,
                             nullable=True,
                             comment="Duration of the df2 grab, in seconds.")
    sum = db.Column(
        db.Float,
        unique=False,
        nullable=True,
        comment=
        "Sum of values for df1 and df2 at end of trial. Dependent variable.")

    def __init__(self, **kwargs):
        super(CircleTaskTrial, self).__init__(**kwargs)
        self.df1_duration = kwargs['df1_release'] - kwargs['df1_grab']
        self.df2_duration = kwargs['df2_release'] - kwargs['df2_grab']
        self.sum = kwargs['df1'] + kwargs['df2']

    def __repr__(self):
        return f"CircleTaskTrial(user_id='{self.user_id}', block_id={self.block_id}, trial={self.trial}, " \
               f"df1={self.df1}, df1_grab={self.df1_grab}, df1_release={self.df1_release}, " \
               f"df2={self.df2}, df2_grab={self.df2_grab}, df2_release={self.df2_release})"
示例#22
0
class CreditCard(ResourceMixin, db.Model):
    IS_EXPIRING_THRESHOLD_MONTHS = 2

    __tablename__ = 'credit_cards'
    id = db.Column(db.Integer, primary_key=True)

    # Relationships.
    user_id = db.Column(db.Integer,
                        db.ForeignKey('users.id',
                                      onupdate='CASCADE',
                                      ondelete='CASCADE'),
                        index=True,
                        nullable=False)

    # Card details.
    brand = db.Column(db.String(32))
    last4 = db.Column(db.Integer)
    exp_date = db.Column(db.Date, index=True)
    is_expiring = db.Column(db.Boolean(), nullable=False, server_default='0')

    def __init__(self, **kwargs):
        # Call Flask-SQLAlchemy's constructor.
        super(CreditCard, self).__init__(**kwargs)

    @classmethod
    def is_expiring_soon(cls, compare_date=None, exp_date=None):
        """
        Determine whether or not this credit card is expiring soon.

        :param compare_date: Date to compare at
        :type compare_date: date
        :param exp_date: Expiration date
        :type exp_date: date
        :return: bool
        """
        return exp_date <= timedelta_months(
            CreditCard.IS_EXPIRING_THRESHOLD_MONTHS, compare_date=compare_date)

    @classmethod
    def mark_old_credit_cards(cls, compare_date=None):
        """
        Mark credit cards that are going to expire soon or have expired.

        :param compare_date: Date to compare at
        :type compare_date: date
        :return: Result of updating the records
        """
        today_with_delta = timedelta_months(
            CreditCard.IS_EXPIRING_THRESHOLD_MONTHS, compare_date)

        CreditCard.query.filter(CreditCard.exp_date <= today_with_delta) \
            .update({CreditCard.is_expiring: True})

        return db.session.commit()

    @classmethod
    def extract_card_params(cls, customer):
        """
        Extract the credit card info from a payment customer object.

        :param customer: Payment customer
        :type customer: Payment customer
        :return: dict
        """
        card_data = customer.sources.data[0]
        exp_date = datetime.date(card_data.exp_year, card_data.exp_month, 1)

        card = {
            'brand': card_data.brand,
            'last4': card_data.last4,
            'exp_date': exp_date,
            'is_expiring': CreditCard.is_expiring_soon(exp_date=exp_date)
        }

        return card
示例#23
0
        return pwd_context.verify(password, self.password)

    def to_json(self):
        json_user = {
            'id': str(self.id),
            'username': self.username,
            'avator': self.avator,
            'email': self.email,
            # 'pictures':self.pictures
        }
        return json_user


# 关联表tag_picture
relation = db.Table('tag_pic_relation',
                    db.Column('id', db.Integer, primary_key=True),
                    db.Column('tag_id', db.Integer, db.ForeignKey('tag.id')),
                    db.Column('picture_id', db.Integer, db.ForeignKey('pictures.id'))
                    )


class Picture(db.Model):
    __tablename__ = 'pictures'
    id = db.Column(db.Integer, primary_key=True)
    despriction = db.Column(db.String(500))
    address = db.Column(db.String(200), unique=True)
    userId = db.Column(db.Integer, db.ForeignKey('user.id'))
    tags = db.relationship(
        'Tag', secondary=relation, backref=db.backref('pictures', lazy='dynamic'))
    comments = db.relationship(
        'Comment', backref='pictures', lazy='dynamic')
示例#24
0
make_searchable()


class NoteQuery(BaseQuery, SearchQueryMixin):
    pass


def sanitize(content):
    soup = BeautifulSoup(content, 'html.parser')
    nodes = soup.recursiveChildGenerator()
    text_nodes = [e for e in nodes if isinstance(e, str)]
    return ''.join(text_nodes)


tags = db.Table('note_tag',
                db.Column('tag.id', db.Integer, db.ForeignKey('tag.id')),
                db.Column('note.id', db.Integer, db.ForeignKey('note.id')))


class Note(db.Model, GetOr404Mixin, GetOrCreateMixin):
    query_class = NoteQuery

    id = db.Column(db.Integer, primary_key=True)
    content = db.Column(db.Text)
    created = db.Column(db.DateTime)
    updated = db.Column(db.DateTime)
    is_email = db.Column(db.Boolean)
    history = db.relationship('NoteHistory', backref='note', cascade='delete')
    user_id = db.Column(db.Integer, db.ForeignKey('user.id'))
    author = db.relationship('User', backref='notes')
    search_vector = db.Column(TSVectorType('content'))
示例#25
0
class Party(AuditMixin, Base):
    __tablename__ = 'party'
    party_guid = db.Column(UUID(as_uuid=True),
                           primary_key=True,
                           server_default=FetchedValue())
    first_name = db.Column(db.String, nullable=True)
    middle_name = db.Column(db.String, nullable=True)
    party_name = db.Column(db.String, nullable=False)
    phone_no = db.Column(db.String, nullable=False)
    phone_ext = db.Column(db.String, nullable=True)
    email = db.Column(db.String, nullable=True)
    effective_date = db.Column(db.DateTime,
                               nullable=False,
                               server_default=FetchedValue())
    expiry_date = db.Column(db.DateTime)
    party_type_code = db.Column(
        db.String, db.ForeignKey('party_type_code.party_type_code'))
    deleted_ind = db.Column(db.Boolean,
                            nullable=False,
                            server_default=FetchedValue())

    mine_party_appt = db.relationship('MinePartyAppointment', lazy='joined')
    address = db.relationship('Address', lazy='joined')
    job_title = db.Column(db.String, nullable=True)
    postnominal_letters = db.Column(db.String, nullable=True)
    idir_username = db.Column(db.String, nullable=True)

    business_role_appts = db.relationship('PartyBusinessRoleAppointment',
                                          lazy='joined')
    party_orgbook_entity = db.relationship('PartyOrgBookEntity',
                                           backref='party_orgbook_entity',
                                           uselist=False,
                                           lazy='select')

    @hybrid_property
    def name(self):
        return self.first_name + ' ' + self.party_name if self.first_name else self.party_name

    @hybrid_property
    def business_roles_codes(self):
        return [
            x.party_business_role_code for x in self.business_role_appts
            if (not x.end_date or x.end_date > datetime.utcnow())
        ]

    @name.expression
    def name(cls):
        return func.concat(cls.first_name, ' ', cls.party_name)

    def __repr__(self):
        return '<Party %r>' % self.party_guid

    # TODO: Remove this once mine_party_appt has been refactored
    def json(self, show_mgr=True, relationships=[]):
        context = {
            'party_guid':
            str(self.party_guid),
            'party_type_code':
            self.party_type_code,
            'phone_no':
            self.phone_no,
            'phone_ext':
            self.phone_ext,
            'email':
            self.email,
            'effective_date':
            self.effective_date.isoformat(),
            'expiry_date':
            self.expiry_date.isoformat()
            if self.expiry_date is not None else None,
            'party_name':
            self.party_name,
            'name':
            self.name,
            'address':
            self.address[0].json() if len(self.address) > 0 else [{}],
            'job_title':
            self.job_title,
            'postnominal_letters':
            self.postnominal_letters,
            'idir_username':
            self.idir_username
        }
        if self.party_type_code == 'PER':
            context.update({
                'first_name': self.first_name,
            })

        if 'mine_party_appt' in relationships:
            context.update({
                'mine_party_appt':
                [item.json() for item in self.mine_party_appt],
            })

        return context

    @classmethod
    def find_by_party_guid(cls, _id):
        try:
            uuid.UUID(_id)
        except ValueError:
            raise BadRequest('Invalid Party guid')
        return cls.query.filter_by(party_guid=_id, deleted_ind=False).first()

    @classmethod
    def find_by_name(cls, party_name, first_name=None):
        party_type_code = 'PER' if first_name else 'ORG'
        filters = [
            func.lower(cls.party_name) == func.lower(party_name),
            cls.party_type_code == party_type_code, cls.deleted_ind == False
        ]
        if first_name:
            filters.append(
                func.lower(cls.first_name) == func.lower(first_name))
        return cls.query.filter(*filters).first()

    @classmethod
    def search_by_name(cls, search_term, party_type=None, query_limit=50):
        _filter_by_name = func.upper(cls.name).contains(
            func.upper(search_term))
        if party_type:
            return cls.query.filter(cls.party_type_code == party_type).filter(
                _filter_by_name).filter(
                    cls.deleted_ind == False).limit(query_limit)
        else:
            return cls.query.filter(_filter_by_name).filter(
                cls.deleted_ind == False).limit(query_limit)

    @classmethod
    def create(
            cls,
            # Required fields
            party_name,
            phone_no,
            party_type_code,
            # Optional fields
            address_type_code=None,
            # Nullable fields
            email=None,
            first_name=None,
            phone_ext=None,
            suite_no=None,
            address_line_1=None,
            address_line_2=None,
            city=None,
            sub_division_code=None,
            post_code=None,
            add_to_session=True):
        party = cls(
            # Required fields
            party_name=party_name,
            phone_no=phone_no,
            party_type_code=party_type_code,
            # Optional fields
            email=email,
            first_name=first_name,
            phone_ext=phone_ext)
        if add_to_session:
            party.save(commit=False)
        return party

    @validates('party_type_code')
    def validate_party_type_code(self, key, party_type_code):
        if not party_type_code:
            raise AssertionError('Party type is not provided.')
        if party_type_code not in ['PER', 'ORG']:
            raise AssertionError('Invalid party type.')
        return party_type_code

    @validates('first_name')
    def validate_first_name(self, key, first_name):
        if self.party_type_code == 'PER' and not first_name:
            raise AssertionError('Person first name is not provided.')
        if first_name and len(first_name) > 100:
            raise AssertionError(
                'Person first name must not exceed 100 characters.')
        return first_name

    @validates('party_name')
    def validate_party_name(self, key, party_name):
        if not party_name:
            raise AssertionError('Party name is not provided.')
        if len(party_name) > 100:
            raise AssertionError('Party name must not exceed 100 characters.')
        return party_name

    @validates('phone_no')
    def validate_phone_no(self, key, phone_no):
        if not phone_no:
            raise AssertionError('Party phone number is not provided.')
        if not re.match(r'[0-9]{3}-[0-9]{3}-[0-9]{4}', phone_no):
            raise AssertionError(
                'Invalid phone number format, must be of XXX-XXX-XXXX.')
        return phone_no

    @validates('email')
    def validate_email(self, key, email):
        if email and not re.match(r'[^@]+@[^@]+\.[^@]+', email):
            raise AssertionError(f'Invalid email format. {email}')
        return email
示例#26
0
class Note(db.Model, GetOr404Mixin, GetOrCreateMixin):
    query_class = NoteQuery

    id = db.Column(db.Integer, primary_key=True)
    content = db.Column(db.Text)
    created = db.Column(db.DateTime)
    updated = db.Column(db.DateTime)
    is_email = db.Column(db.Boolean)
    history = db.relationship('NoteHistory', backref='note', cascade='delete')
    user_id = db.Column(db.Integer, db.ForeignKey('user.id'))
    author = db.relationship('User', backref='notes')
    search_vector = db.Column(TSVectorType('content'))
    tags = db.relationship('Tag', backref='notes', secondary=tags)

    class VersionDoesNotExist(Exception):
        def __init__(self, note, version):
            super(Note.VersionDoesNotExist, self).__init__(
                'Note version {} not found in history of note {}'.format(
                    version, note.id))

    @classmethod
    def create(cls, content, author, is_email=False):
        note = Note(content=sanitize(content),
                    author=author,
                    is_email=is_email)
        note.created = datetime.datetime.utcnow()
        note.updated = note.created
        db.session.add(note)
        db.session.commit()
        return note

    def update(self, content):
        now = datetime.datetime.utcnow()
        version = NoteHistory(self, now)
        db.session.add(version)
        self.history.append(version)
        self.content = sanitize(content)
        self.updated = now
        db.session.add(self)
        db.session.commit()

    def revert(self, version=None):
        if version is None:
            version = len(self.history) - 1

        versions = {rev.version: rev for rev in self.history}

        if version not in versions:
            raise Note.VersionDoesNotExist(self, version)

        self.update(versions[version].content)

    def delete(self):
        db.session.delete(self)
        db.session.commit()

    def add_tag(self, tag_name):
        if tag_name and not self.has_tag(tag_name):
            self.tags.append(Tag(name=sanitize(tag_name), author=self.author))
            db.session.add(self)
            db.session.commit()

    def has_tag(self, tag_name):
        return Note.query.join(tags).filter(Note.id == self.id, Tag.author
                                            == self.author, Tag.name
                                            == tag_name).count() > 0

    def remove_tag(self, tag_name):
        if self.has_tag(tag_name):
            tag = [tag for tag in self.tags if tag.name == tag_name]
            self.tags.remove(tag[0])
            db.session.add(self)
            db.session.commit()

    @classmethod
    def search(cls, term, user):
        return Note.query.filter(Note.author == user).search(term, sort=True)

    @property
    def rendered(self):
        markdown = current_app.jinja_env.filters['markdown']
        return markdown(self.content)

    @property
    def truncated(self):
        truncate = current_app.jinja_env.filters['truncate_html']
        return truncate(self.rendered, 250, end=" \u2026")

    @property
    def edit_url(self):
        return url_for('notes.edit', id=self.id)

    @property
    def just_updated(self):
        undo_timeout = (datetime.datetime.utcnow() -
                        datetime.timedelta(minutes=2))
        return bool(self.history and self.updated > undo_timeout)

    @property
    def undo_url(self):
        return url_for('notes.undo', id=self.id)

    @property
    def timestamp(self):
        return self.updated.strftime('%Y%m%d%H%M%S.%f')

    @property
    def friendly_updated(self):
        humanize = current_app.jinja_env.filters['humanize']
        return humanize(self.updated)

    def json(self):
        return {
            'id': self.id,
            'truncated': self.truncated,
            'edit_url': self.edit_url,
            'content': self.content,
            'just_updated': self.just_updated,
            'undo_url': self.undo_url,
            'timestamp': self.timestamp,
            'friendly_updated': self.friendly_updated,
            'is_email': self.is_email,
            'tags': [{
                'name': tag.name,
                'url': tag.url
            } for tag in self.tags]
        }
示例#27
0
class User(MerchantBase):
    """
    用户,按商户分库
    """
    id = db.Column(db.Integer,
                   primary_key=True,
                   autoincrement=False,
                   comment='用户ID,主键但不自增,由全局表生成id')
    _create_time = db.Column('create_time',
                             db.Integer,
                             nullable=False,
                             comment="创建时间",
                             index=True)

    account = db.Column(db.String(32), comment="账号,手机号码/邮箱", nullable=False)
    _ac_type = db.Column('ac_type',
                         db.SmallInteger,
                         default=AccountTypeEnum.NONE.value,
                         comment="账号类型,手机号码/邮箱")
    _state = db.Column('state',
                       db.SmallInteger,
                       default=AccountStateEnum.ACTIVE.value,
                       comment="账号状态")
    _login_pwd = db.Column('login_pwd', db.String(100), comment="登录密码,已加密存储")
    _trade_pwd = db.Column('trade_pwd', db.String(100), comment="支付密码,已加密存储")
    _flag = db.Column('flag', db.SmallInteger, comment="账号状态", nullable=True)
    _permissions = db.Column('permissions',
                             db.SmallInteger,
                             comment="账号权限",
                             nullable=True)

    __table_args__ = (
        # 联合唯一索引
        db.UniqueConstraint('account',
                            'merchant',
                            name='uix_user_account_mch_name'),
        # 联合索引
        # db.Index('ix_user_account_mch_name', 'account', 'merchant'),
    )

    _merchant = db.Column('merchant',
                          db.Integer,
                          comment="商户ID",
                          nullable=False)

    @property
    def merchant(self) -> MerchantEnum:
        return MerchantEnum(self._merchant)

    @merchant.setter
    def merchant(self, merchant: MerchantEnum):
        self._merchant = merchant.value

    @property
    def permissions(self) -> List[UserPermissionEnum]:
        if not self._permissions:
            return UserPermissionEnum.get_all_enums()
        return UserPermissionEnum.parse_permissions(self._permissions)

    @permissions.setter
    def permissions(self, values: List[UserPermissionEnum]):
        self._permissions = UserPermissionEnum.join_permissions(values)

    @property
    def permission_names(self):
        return [x.name for x in self.permissions]

    def has_permission(self, perm: UserPermissionEnum):
        """
        判断用户是否有权限
        :param perm:
        :return:
        """
        if not self._permissions:
            # 未设置权限,拥有所有权限
            return True
        return perm.has_permission(self._permissions)

    @property
    def flag(self) -> AccountFlagEnum:
        if not self._flag:
            return AccountFlagEnum.NORMAL
        return AccountFlagEnum(self._flag)

    @flag.setter
    def flag(self, value: AccountFlagEnum):
        if value:
            self._flag = value.value

    @property
    def is_official_auth(self):
        return self.flag == AccountFlagEnum.VIP

    @property
    def is_test_user(self):
        """
        是否是测试用户
        :return:
        """
        return self.merchant.is_test

    @property
    def uid(self):
        return self.id

    @property
    def is_active(self):
        return self._state == AccountStateEnum.ACTIVE.value

    @property
    def state(self) -> AccountStateEnum:
        return AccountStateEnum(self._state)

    @state.setter
    def state(self, value: AccountStateEnum):
        self._state = value.value

    @property
    def ac_type(self):
        """
        返回账户枚举类型
        :return:
        """
        return AccountTypeEnum(self._ac_type)

    @ac_type.setter
    def ac_type(self, e_value):
        """
        传入账户的类型
        :param e_value:
        :return:
        """
        if e_value:
            self._ac_type = e_value.value

    @property
    def login_pwd(self):
        """
        登录密码
        :return:
        """
        return self._login_pwd

    @login_pwd.setter
    def login_pwd(self, raw_pwd):
        """
        设置密码时要进行加密
        :param raw_pwd:
        :return:
        """
        if raw_pwd:
            self._login_pwd = generate_password_hash(raw_pwd)

    @property
    def trade_pwd(self):
        """
        交易密码
        :return:
        """
        return self._trade_pwd

    @trade_pwd.setter
    def trade_pwd(self, raw_pwd):
        """
        设置交易密码
        :param raw_pwd:
        :return:
        """
        if raw_pwd:
            self._trade_pwd = generate_password_hash(raw_pwd)

    def has_trade_pwd(self):
        return bool(self.trade_pwd)

    @classmethod
    def generate_model(cls,
                       merchant,
                       account,
                       ac_type: AccountTypeEnum = None,
                       login_pwd=None):
        """
        生成用户模型
        :param merchant:
        :param account:
        :param ac_type:
        :param login_pwd:
        :return:
        """
        user = cls.get_model_obj(merchant=merchant)
        user.account = account
        user.ac_type = ac_type
        user.login_pwd = login_pwd
        user.merchant = merchant
        user.id = 0
        return user

    @classmethod
    def register_account(cls,
                         merchant,
                         account,
                         ac_type: AccountTypeEnum = None,
                         login_pwd=None):
        """
        注册账号
        :param merchant:
        :param account:
        :param ac_type:
        :param login_pwd:
        :return:
        """
        uid = GlobalUid.make_uid(merchant)

        with db.auto_commit():
            user = cls.generate_model(merchant, account, ac_type, login_pwd)
            user.id = uid
            db.session.add(user)

            balance = UserBalance.generate_model(user.uid, merchant)
            db.session.add(balance)

        return user

    @classmethod
    def delete_account(cls, merchant, uid=None, account=None):
        """
        删除账号
        :param uid:
        :param account:
        :param merchant:
        :return:
        """
        with db.auto_commit():
            user = cls.query_user(merchant, uid=uid, account=account)
            db.session.delete(user)

    @classmethod
    def update_user_state(cls, merchant, account=None, uid=None, state=None):
        """
        修改用户状态
        :param merchant:
        :param account:
        :param uid:
        :param state:
        :return:
        """
        with db.auto_commit():
            if not account:
                user = cls.query_user(merchant=merchant, uid=uid)
            else:
                user = cls.query_user(merchant=merchant, account=account)
            if user is not None:
                user.state = state
                db.session.add(user)
                return True
            else:
                return False

    @classmethod
    def update_user_flag(cls,
                         merchant,
                         flag: AccountFlagEnum,
                         account=None,
                         uid=None):
        """
        修改用户标签
        """
        if account:
            user = cls.query_user(merchant=merchant, account=account)
        else:
            user = cls.query_user(merchant=merchant, uid=uid)

        if user is not None:
            user.flag = flag
            cls.commit_models(user)
            UserFlagCache(user.uid).set_flag(flag)
            return True

        return False

    @classmethod
    def update_user_permission(cls,
                               merchant,
                               permissions: List[UserPermissionEnum],
                               account=None,
                               uid=None):
        """
        修改用户权限
        """
        if account:
            user = cls.query_user(merchant=merchant, account=account)
        else:
            user = cls.query_user(merchant=merchant, uid=uid)

        if user is not None:
            user.permissions = permissions
            cls.commit_models(user)
            return True

        return False

    @classmethod
    def reset_password(cls, merchant, account=None, uid=None, login_pwd=None):
        """
        修改密码
        :param merchant:
        :param account:
        :param uid:
        :param login_pwd:
        :return:
        """
        with db.auto_commit():
            if not account:
                user = cls.query_user(merchant=merchant, uid=uid)
            else:
                user = cls.query_user(merchant=merchant, account=account)
            if user is not None:
                user.login_pwd = login_pwd
                db.session.add(user)
                return True
            else:
                return False

    @classmethod
    def verify_login(cls, merchant, account, password):
        """
        账号密码鉴权
        :param merchant:
        :param account:
        :param password:
        :return:
        """
        user = cls.query_user(merchant, account=account)
        if not user:
            return False

        return user.check_login_pwd(password)

    @classmethod
    def verify_password(cls, merchant, uid, password):
        """
        账号密码鉴权
        :param merchant:
        :param uid:
        :param password:
        :return:
        """
        user = cls.query_user(merchant, uid=uid)
        if not user:
            return False

        return user.check_login_pwd(password)

    def check_login_pwd(self, raw_pwd):
        return check_password_hash(self._login_pwd, raw_pwd)

    @classmethod
    def query_user(cls, merchant, uid=None, account=None):
        """
        查询用户
        :param merchant:
        :param uid:
        :param account:
        :return:
        """
        if uid:
            kwargs = dict(id=int(uid))
        elif account:
            kwargs = dict(account=account, )
        else:
            raise ValueError('parameter error')

        kwargs['_merchant'] = merchant.value

        return cls.query_one(query_fields=kwargs)

    @classmethod
    def set_payment_password(cls,
                             merchant,
                             account=None,
                             uid=None,
                             trade_pwd=None):
        """
        修改密码
        :param merchant:
        :param account:
        :param uid:
        :param trade_pwd:
        :return:
        """
        with db.auto_commit():
            if not account:
                user = cls.query_user(merchant=merchant, uid=uid)
            else:
                user = cls.query_user(merchant=merchant, account=account)
            if user is not None:
                user.trade_pwd = trade_pwd
                db.session.add(user)
                return True
            else:
                return False

    @classmethod
    def verify_payment_password(cls, merchant, uid, password):
        """
        支付密码鉴权
        :param merchant:
        :param uid:
        :param password:
        :return:
        """
        user = cls.query_user(merchant, uid=uid)
        if not user:
            return False

        return user.check_trade_pwd(password)

    def check_trade_pwd(self, raw_pwd):
        """
        验证交易密码
        :param raw_pwd:
        :return:
        """
        if not self._trade_pwd:
            return False

        return check_password_hash(self._trade_pwd, raw_pwd)
示例#28
0
class ContractedWorkPayment(Base, AuditMixin):
    __tablename__ = 'contracted_work_payment'

    def __init__(self, application, contracted_work_payment_status_code,
                 contracted_work_payment_code, **kwargs):
        super(ContractedWorkPayment, self).__init__(**kwargs)
        initial_status = ContractedWorkPaymentStatusChange(
            contracted_work_payment=self,
            application=application,
            contracted_work_payment_status_code=
            contracted_work_payment_status_code,
            contracted_work_payment_code=contracted_work_payment_code)
        self.status_changes.append(initial_status)

    contracted_work_payment_id = db.Column(db.Integer, primary_key=True)
    application_guid = db.Column(UUID(as_uuid=True),
                                 db.ForeignKey('application.guid'),
                                 nullable=False)
    work_id = db.Column(db.String, unique=True, nullable=False)

    interim_actual_cost = db.Column(db.Numeric(14, 2))
    final_actual_cost = db.Column(db.Numeric(14, 2))

    interim_paid_amount = db.Column(db.Numeric(14, 2))
    final_paid_amount = db.Column(db.Numeric(14, 2))

    interim_total_hours_worked_to_date = db.Column(db.Numeric(14, 2))
    final_total_hours_worked_to_date = db.Column(db.Numeric(14, 2))

    interim_number_of_workers = db.Column(db.Integer)
    final_number_of_workers = db.Column(db.Integer)

    work_completion_date = db.Column(db.Date)

    interim_submitter_name = db.Column(db.String)
    final_submitter_name = db.Column(db.String)

    interim_eoc_application_document_guid = db.Column(
        UUID(as_uuid=True),
        db.ForeignKey('application_document.application_document_guid'),
        unique=True)
    final_eoc_application_document_guid = db.Column(
        UUID(as_uuid=True),
        db.ForeignKey('application_document.application_document_guid'),
        unique=True)

    final_report_application_document_guid = db.Column(
        UUID(as_uuid=True),
        db.ForeignKey('application_document.application_document_guid'),
        unique=True)

    interim_eoc_document = db.relationship(
        'ApplicationDocument',
        lazy='selectin',
        foreign_keys=[interim_eoc_application_document_guid])
    final_eoc_document = db.relationship(
        'ApplicationDocument',
        lazy='selectin',
        foreign_keys=[final_eoc_application_document_guid])

    interim_report = db.Column(db.String)
    final_report_document = db.relationship(
        'ApplicationDocument',
        lazy='selectin',
        foreign_keys=[final_report_application_document_guid])

    status_changes = db.relationship(
        'ContractedWorkPaymentStatusChange',
        lazy='selectin',
        order_by='desc(ContractedWorkPaymentStatusChange.change_timestamp)')

    payment_documents = db.relationship(
        'PaymentDocument',
        lazy='selectin',
        secondary='payment_document_contracted_work_payment_xref')

    # Auditing
    audit_ind = db.Column(db.Boolean)
    audit_user = db.Column(db.String)
    audit_timestamp = db.Column(db.DateTime)

    # General Reporting
    surface_landowner = db.Column(db.String)
    reclamation_was_achieved = db.Column(db.Boolean)

    # Abandonment Reporting
    abandonment_cut_and_capped_completed = db.Column(db.Boolean)
    abandonment_notice_of_operations_submitted = db.Column(db.Boolean)
    abandonment_was_pipeline_abandoned = db.Column(db.Boolean)
    abandonment_metres_of_pipeline_abandoned = db.Column(db.Integer)

    # PSI and DSI Reporting
    site_investigation_type_of_document_submitted = db.Column(db.String)
    site_investigation_concerns_identified = db.Column(db.Boolean)

    # Remediation Reporting
    remediation_identified_contamination_meets_standards = db.Column(
        db.Boolean)
    remediation_type_of_document_submitted = db.Column(db.String)
    remediation_reclaimed_to_meet_cor_p1_requirements = db.Column(db.Boolean)

    # Reclamation Reporting
    reclamation_reclaimed_to_meet_cor_p2_requirements = db.Column(db.Boolean)
    reclamation_surface_reclamation_criteria_met = db.Column(db.Boolean)

    @hybrid_property
    def has_interim_prfs(self):
        if self.payment_documents:
            return any(
                doc.active_ind and doc.payment_document_code == 'INTERIM_PRF'
                for doc in self.payment_documents)
        return False

    @hybrid_property
    def has_final_prfs(self):
        if self.payment_documents:
            return any(
                doc.active_ind and doc.payment_document_code == 'FINAL_PRF'
                for doc in self.payment_documents)
        return False

    @hybrid_property
    def interim_payment_status_code(self):
        if self.interim_payment_status:
            return self.interim_payment_status.contracted_work_payment_status_code
        else:
            return 'INFORMATION_REQUIRED'

    @hybrid_property
    def interim_payment_status(self):
        if self.interim_payment_status_changes:
            return self.interim_payment_status_changes[0]

    @hybrid_property
    def interim_payment_status_changes(self):
        return [
            status for status in self.status_changes
            if status.contracted_work_payment_code == 'INTERIM'
        ]

    @hybrid_property
    def interim_payment_submission_date(self):
        if self.interim_payment_status_changes:
            return self.interim_payment_status_changes[-1].change_timestamp

    @hybrid_property
    def final_payment_status_code(self):
        if self.final_payment_status:
            return self.final_payment_status.contracted_work_payment_status_code
        else:
            return 'INFORMATION_REQUIRED'

    @hybrid_property
    def final_payment_status(self):
        if self.final_payment_status_changes:
            return self.final_payment_status_changes[0]

    @hybrid_property
    def final_payment_status_changes(self):
        return [
            status for status in self.status_changes
            if status.contracted_work_payment_code == 'FINAL'
        ]

    @hybrid_property
    def final_payment_submission_date(self):
        if self.final_payment_status_changes:
            return self.final_payment_status_changes[-1].change_timestamp

    @hybrid_property
    def review_deadlines(self):
        review_deadlines = {
            'interim': REVIEW_DEADLINE_NOT_APPLICABLE,
            'final': REVIEW_DEADLINE_NOT_APPLICABLE
        }

        interim_payment_submission_date = self.interim_payment_submission_date
        final_payment_submission_date = self.final_payment_submission_date

        # No payment information has been submitted
        if interim_payment_submission_date is None and final_payment_submission_date is None:
            return review_deadlines

        # We don't need to review payments that have already had at least one PRF issued
        if interim_payment_submission_date and self.has_interim_prfs:
            interim_payment_submission_date = None
            review_deadlines['interim'] = REVIEW_DEADLINE_PAID
        if final_payment_submission_date and self.has_final_prfs:
            final_payment_submission_date = None
            review_deadlines['final'] = REVIEW_DEADLINE_PAID

        # Both interim and final have been submitted and have completed the payment process
        if interim_payment_submission_date is None and final_payment_submission_date is None:
            return review_deadlines

        days_to_review = timedelta(days=90)

        if interim_payment_submission_date:
            interim_deadline = interim_payment_submission_date + days_to_review
            review_deadlines['interim'] = interim_deadline

        if final_payment_submission_date:
            final_deadline = final_payment_submission_date + days_to_review
            review_deadlines['final'] = final_deadline

        return review_deadlines

    def __repr__(self):
        return f'<{self.__class__.__name__} {self.contracted_work_payment_id} {self.application_guid} {self.work_id}>'

    @classmethod
    def find_by_application_guid(cls, application_guid):
        return cls.query.filter_by(application_guid=application_guid).all()

    @classmethod
    def find_by_work_id(cls, work_id):
        return cls.query.filter_by(work_id=work_id).one_or_none()
示例#29
0
# -*- coding: utf-8 -*-
"""
Base models
"""

from flask_security import RoleMixin, UserMixin
from sqlalchemy.orm.exc import MultipleResultsFound, NoResultFound

from app.extensions import db
from lib.model_utils import GetOr404Mixin, GetOrCreateMixin

user_roles = db.Table(
    'user_roles', db.Column('user_id', db.Integer, db.ForeignKey('user.id')),
    db.Column('role_id', db.Integer, db.ForeignKey('role.id')))


class Role(db.Model, RoleMixin):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(50), unique=True)
    description = db.Column(db.String(255))


class User(db.Model, UserMixin, GetOrCreateMixin, GetOr404Mixin):
    id = db.Column(db.Integer, primary_key=True)
    email = db.Column(db.String(255), unique=True)
    password = db.Column(db.String)
    full_name = db.Column(db.String)
    inbox_email = db.Column(db.String(255), unique=True)
    active = db.Column(db.Boolean)
    confirmed_at = db.Column(db.DateTime)
    roles = db.relationship('Role',
示例#30
0
class Comment(PaginatedAPIMixin, db.Model):
    """评论模型类"""
    __tablename__ = 'comments'
    id = db.Column(db.Integer, primary_key=True)
    body = db.Column(db.TEXT)
    timestamp = db.Column(db.DateTime, index=True)
    mark_read = db.Column(db.Boolean, default=False)  # 是否已读
    disabled = db.Column(db.Boolean, default=False)  # 屏蔽显示
    # 评论者的id
    author_id = db.Column(db.Integer, db.ForeignKey('users.id'))
    # 评论博文的id
    post_id = db.Column(db.Integer, db.ForeignKey('posts.id'))
    # 父评论id
    parent_id = db.Column(db.Integer,
                          db.ForeignKey('comments.id', ondelete='CASCADE'))
    parent = db.relationship('Comment', backref= \
        db.backref('children', cascade='all,delete-orphan'), remote_side=[id])
    likers = db.relationship('User',
                             secondary=comments_likes,
                             backref=db.backref('liked_comments',
                                                lazy='dynamic'))

    def __repr__(self):
        """控制台输出"""
        return "<Comment {}>".format(self.id)

    def get_descendants(self):
        '''获取一级评论的所有子孙'''
        data = set()

        def descendants(comment):
            if comment.children:
                data.update(comment.children)
                for child in comment.children:
                    descendants(child)

        descendants(self)
        return data

    def get_ancestors(self):
        """获取评论的所有爸爸们"""
        data = []

        def ancestors(comment):
            if comment.parent:
                data.append(comment.parent)
                ancestors(comment.parent)

        ancestors(self)
        return data

    def from_dict(self, data: dict):
        """填充数据至当前模型类"""
        for filed in [
                'body', 'timestamp', 'mark_read', 'disabled', 'post_id',
                'parent_id'
        ]:
            setattr(self, filed, data[filed])

    def to_dict(self) -> dict:
        """序列化评论模型"""
        data = {
            'id': self.id,
            'body': self.body,
            'timestamp': self.timestamp,
            'mark_read': self.mark_read,
            'disabled': self.disabled,
            'author': {
                'id': self.author.id,
                'username': self.author.username,
                'name': self.author.name,
                'avatar': self.author.avatar(128)
            },
            'post': {
                'id': self.post.id,
                'title': self.post.title,
                'author_id': self.post.author.id
            },
            'parent_id': self.parent_id if self.parent else None,
            '_links': {
                'self':
                url_for('api.get_comment', id=self.id),
                'author_url':
                url_for('api.get_user', id=self.author_id),
                'post_url':
                url_for('api.get_post', id=self.post_id),
                'parent_url':
                url_for('api.get_comment', id=self.parent_id)
                if self.parent else None,
                'children_url': [
                    url_for('api.get_comment', id=child.id)
                    for child in self.children
                ] if self.childeren else None
            }
        }

        return data

    def is_liked_by(self, user):
        """用户是否点赞"""
        return user in self.likers

    def liked_by(self, user):
        """点赞评论"""
        if not self.is_liked_by(user):
            self.likers.append(user)

    def un_liked_by(self, user):
        """取消点赞"""
        if self.is_liked_by(user):
            self.likers.remove(user)