Exemple #1
0
class RecruitingCycle(db.Document):
    url = db.StringField(max_length=70)
class ControlData(db.EmbeddedDocument):
    controlTopic = db.StringField()
    controlStatus = db.FloatField()
class Wifi(db.Document):
    ssid = db.StringField()
    password = db.StringField()
    meta = {'max_documents': 1, 'max_size': 200}
class Role(db.Document, RoleMixin):
    name = db.StringField(max_length=255)
class Controls(db.Document):
    groupName = db.StringField()
    rooms = db.ListField(db.EmbeddedDocumentField(Rooms))
    meta = {'collection': 'controls', 'queryset_class': BaseQuerySet}
Exemple #6
0
class Role(db.Document):
    pkid = db.IntField(required=True)
    name = db.StringField(required=True, max_length=100)
    index = db.StringField(required=True)
    permissions = db.DictField(required=True)
    default = db.BooleanField(required=True, default=False)
    enable = db.BooleanField(required=True, default=True)
    createtime = db.DateTimeField(required=True,
                                  default=arrow.utcnow().datetime)

    meta = {
        'db_alias': 'account',
        'collection': 'role',
        'allow_inheritance': True
    }

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

    def save(self):
        if self.pkid is None:
            self.pkid = Counter.get_id('role')
        super(Role, self).save()

    def to_json(self):
        return {
            "pkid": self.pkid,
            "name": self.name,
            "index": self.index,
            "permissions": self.permissions,
        }

    def get_pkid(self):
        return str(self.pkid)

    @staticmethod
    def insert_roles():
        permissions = Permission().to_json()
        roles = dict()
        roles['User'] = dict(
            permissions=permissions,
            index='account',
            default=True,
            enable=True,
        )

        permissions['content_audit'] = True
        permissions['content_manage'] = True
        roles['Manager'] = dict(
            permissions=permissions,
            index='admin',
            default=False,
            enable=True,
        )

        permissions['account_manage'] = True
        permissions['administer'] = True
        roles['Administrator'] = dict(
            permissions=permissions,
            index='admin',
            default=False,
            enable=True,
        )

        for k, v in roles.items():
            role = Role.objects(name=k).first()
            if role is None:
                role = Role(name=k)
            role.permissions = v['permissions']
            role.index = v['index']
            role.default = v['default']
            role.enable = v['enable']
            role.save()

    def add_permission(self, perm):
        if not self.has_permission(perm):
            self.permissions[perm] = True

    def remove_permission(self, perm):
        if self.has_permission(perm):
            self.permissions[perm] = False

    def reset_permissions(self):
        self.permissions = Permission().to_json()

    def has_permission(self, perm):
        return self.permissions[perm]

    def __repr__(self):
        return '<Role %r>' % self.name
Exemple #7
0
class Note(db.Document):
    title = db.StringField(required=True, max_length=120)
    content = db.StringField()
    last_updated = db.DateTimeField(default=datetime.datetime.now())
    user = db.ReferenceField(User)
Exemple #8
0
class Category(db.Document):
    category = db.StringField(required=True, Unique=True, max_length=10)
Exemple #9
0
class Payment(db.Document):
    """"""
    meta = {
        'db_alias': 'db_order',
        'indexes': ['order', 'ptype', '-created_at'],
    }

    created_at = db.DateTimeField(default=datetime.datetime.utcnow(),
                                  required=True)
    order = db.ReferenceField('Order')
    logistic = db.ReferenceField('Logistic')

    other_reason = db.StringField()
    ptype = db.StringField(required=True, choices=PAYMENT_TYPE)
    status = db.StringField(max_length=256,
                            required=True,
                            choices=PAYMENT_STATUS,
                            default=PAYMENT_STATUS.UNPAID)

    # transaction reference number from alipay/bank
    ref_number = db.StringField(max_length=128)
    paid_amount = db.FloatField()
    foreign_amount = db.FloatField()
    currency = db.StringField()
    buyer_id = db.StringField(max_length=50)
    trader = db.StringField(choices=PAYMENT_TRADERS)
    trade_type = db.StringField(choices=TRADE_TYPE)
    trade_status = db.StringField()
    trader_msg = db.StringField()
    extra = db.StringField()
    modified = db.DateTimeField()
    redirect_url = db.StringField()

    @property
    def is_paid(self):
        return self.status == PAYMENT_STATUS.PAID

    @property
    def amount(self):
        if self.ptype == PAYMENT_TYPE.WITHOUT_TAX:
            return self.order.final
        if self.ptype == PAYMENT_TYPE.WITH_TAX:
            return self.order.final + self.order_tax

    def mark_paid(self, data):
        if self.is_paid:
            return
        self.update(set__status=PAYMENT_STATUS.PAID)
        kwargs = {'set__' + key: value for key, value in data.items()}
        self.update(**kwargs)
        self.reload()
        paid_amount = float(data.get('paid_amount', 0))
        if self.ptype == PAYMENT_TYPE.WITHOUT_TAX:
            self.order.update_payment(self.ptype, paid_amount, self.trader)

    def to_json(self):
        return dict(id=self.id,
                    ref_num=self.ref_number,
                    status=self.status,
                    type=self.type,
                    amount=self.amount)
Exemple #10
0
class Table(db.Document):
    number = db.StringField()
    owner = db.ReferenceField(User)
    url = db.StringField()
    empty = True
Exemple #11
0
class Requests(db.Document):
    tableid = db.ReferenceField(Table)
    table_number = db.StringField()
    time = db.DateTimeField()
    wait_minutes = db.DateTimeField()
    owner = db.ReferenceField(User)
Exemple #12
0
class Todo(db.Document):
    content = db.StringField()
    time = db.DateTimeField(default=datetime.datetime.now())
    status = db.IntField(default=0)
Exemple #13
0
class Users(db.Document):
    username = db.StringField(required=True, unique=True)
    password = db.StringField(required=True)
    email = db.EmailField(required=True)
Exemple #14
0
class Capital(db.Document):
    '''
    coin	str	货币代码
    name	str	货币名称
    marketcap	str	市值(美元)
    price	float	当前时间价格(美元)
    vol24	float	24小时成交额(美元)
    supply	float	流通总量
    date	str	交易日期
    ctime	datetime	数据采集时间
    '''
    _id = db.StringField()
    coin = db.StringField(required=True)
    name = db.StringField(required=True)
    marketcap = db.StringField(required=True)
    price = db.FloatField(required=True, default=0)
    vol24 = db.FloatField(required=True, default=0)
    supply = db.FloatField(required=True, default=0)
    time = db.DateTimeField(required=True)
    ctime = db.DateTimeField(required=True, default=arrow.utcnow().datetime)
    utime = db.DateTimeField(required=True, default=arrow.utcnow().datetime)

    meta = {'db_alias': 'market', 'collection': 'capital', 'strict': False}

    def to_json(self, key=True):
        if key:
            return {
                "coin": self.coin.upper(),
                "name": self.name,
                "marketcap": self.marketcap,
                "price": self.price,
                "vol24": self.vol24,
                "supply": self.supply,
                "time": self.time,
                "ctime": arrow.get(self.ctime).float_timestamp,
            }
        else:
            return [
                arrow.get(self.time).float_timestamp,
                self.name,
                self.marketcap,
                self.price,
                self.vol24,
                self.supply,
            ]

    def __repr__(self):
        return '<Trade name:\'%s\', marketcap:\'%s\'>' % (self.name,
                                                          self.marketcap)

    @staticmethod
    def get_within(coin=None,
                   date=None,
                   start_time=None,
                   end_time=None,
                   key=True):
        '''
        获取时间区间内的数据
        :param coin:
        :param date:
        :param start_time:
        :param end_time:
        :param key:
        :return:
        '''
        query = Capital.objects
        if coin:
            query = query.filter(coin=coin)
        if date:
            query = query.filter(date=date)
        if freq:
            query = query.filter(freq=freq)
        if start_time:
            start_time = arrow.get(start_time).datetime
            query = query.filter(time__gte=start_time)
        if end_time:
            end_time = arrow.get(end_time).datetime
            query = query.filter(time__lt=end_time)

        data_list = query.order_by("time").all()
        result = []
        if data_list:
            for data in data_list:
                result.append(data.to_json(key))

        return result

    @staticmethod
    def insert_data(data):
        if 'coin' not in data or 'marketcap' not in data or 'time' not in data:
            raise Exception('params missed')

        # 检测,防止重复插入
        capital = Capital.objects(coin=data['coin'],
                                  marketcap=data['marketcap'],
                                  time=data['time']).first()

        if not capital:
            return Capital(**data).save()
        else:
            # 只更新当天的,过去的数据不用改变,所以不用更新
            new_time = arrow.get(data['time']).datetime
            old_time = arrow.get(capital.time).datetime
            if new_time == old_time:
                update_data = dict()
                if 'marketcap' in data and data[
                        'marketcap'] != capital.marketcap:
                    update_data['marketcap'] = data['marketcap']
                if 'price' in data and data['price'] != capital.price:
                    update_data['price'] = data['price']
                if 'vol24' in data and data['vol24'] != capital.vol24:
                    update_data['vol24'] = data['vol24']
                if 'supply' in data and data['supply'] != capital.supply:
                    update_data['supply'] = data['supply']
                if update_data:
                    print('Capital update:', capital._id, update_data)
                    update_data['utime'] = arrow.utcnow().datetime
                    Capital.objects(_id=capital._id).update_one(**update_data)
            return True
Exemple #15
0
class Tip(db.Document):
    """
    Represents the definition of a tip in the
    repository.

    Fields:
    tip_name                Name of the tip. Required.
                                    takes a string.

    description             Brief description of the tip. Required.
                                    takes a string

    difficulty              Level of difficulty for the tip. Required.
                                    takes a string: 'beginner', 'intermediate', or 'advanced'

    media_type              Type of supplemental media. Required.
                                    takes a string: 'No Supplemental Media', 'Video', or 'Audio

    media_url               Audio component. Optional.
                                    takes a string.

    video_id                ID of a youtube video, used to embed. Optional.
                                    takes a string.

    submitter               Name of the submitter. Required.
                                    takes a string

    equipment               Names of equipment that might relate to this tip. Optional.
                                    takes a list of strings

    ingredients             Names of ingredients that might relate to this tip. Optional.
                                    takes a list of strings

    techniques              Names of techniques that might relate to this tip. Optional.
                                    takes a list of strings

    instructions            Main text of the tip.
                                    takes a string

    tags                    List of the categories it falls into
                                    takes a list of strings (method, ingredient, equipment)
    """
    query_class = TipQuery
    tip_name = db.StringField(required=True)
    description = db.StringField(required=True)
    difficulty = db.StringField(required=True)
    media_type = db.StringField(required=True)
    media_url = db.StringField(required=False)
    video_id = db.StringField(required=False)
    submitter = db.StringField(required=False)
    equipment = db.ListField(db.StringField(required=False), required=False)
    ingredients = db.ListField(db.StringField(required=False), required=False)
    techniques = db.ListField(db.StringField(required=False), required=False)
    instructions = db.ListField(db.StringField(required=False), required=False)
    tags = db.ListField(db.StringField(required=False), required=False)

    def get_id(self):
        return str(self.mongo_id)
Exemple #16
0
class Order(db.Document):
    """"""
    meta = {
        'db_alias':
        'db_order',
        'ordering': ['-created_at'],
        'indexes': [
            'customer_id', 'status', 'address', 'amount', 'final',
            'order_type', 'is_paid', 'is_payment_abnormal', 'refund_entries'
        ],
    }
    created_at = db.DateTimeField(default=datetime.datetime.utcnow,
                                  required=True)
    order_type = db.StringField(choices=ORDER_TYPE,
                                default=ORDER_TYPE.COMMODITY)
    # one day
    expired_in = db.IntField(default=1440)  # in minutes
    payment_expired_in = db.IntField(default=1440)
    short_id = db.SequenceField(required=True, unique=True)
    is_vip = db.BooleanField(default=False)
    status = db.StringField(max_length=256,
                            required=True,
                            choices=ORDER_STATUS,
                            default=ORDER_STATUS.PAYMENT_PENDING)
    status_modified = db.DateTimeField()
    source = db.StringField(choices=ORDER_SOURCES)
    is_rewards_given = db.BooleanField(default=False)

    # order detail
    amount_usd = db.FloatField(default=0)
    amount = db.FloatField(default=0)

    discount = db.ListField(db.DictField())
    # 优惠卷兑换码
    coupon_codes = db.ListField(db.StringField())
    coin = db.IntField()
    lucky_money = db.IntField()
    cash = db.IntField()
    final = db.FloatField(required=True)
    # 库存
    logistic_provider = db.StringField()
    # 预估退税
    estimated_tax = db.FloatField(default=0)
    real_tax = db.FloatField(default=-1)
    paid_tax = db.FloatField(default=-1)

    # for internal usage
    # 汇率
    forex = db.FloatField()
    real_shipping = db.FloatField()
    cn_shipping = db.FloatField(default=0)
    address = db.ReferenceField('Address')
    customer_id = db.ObjectIdField(required=True)
    is_new_customer = db.BooleanField(default=False)
    entries = db.ListField(
        db.ReferenceField('OrderEntry', reverse_delete_rule=mongoengine.PULL))
    extra = db.StringField()

    logistics = db.ListField(db.ReferenceField('Logistic'))  # 库存
    closed_logistics = db.ListField(db.ReferenceField('Logistic'))

    is_paid = db.BooleanField(default=False)  # 是否支付
    is_payment_abnormal = db.BooleanField(default=False)  # 是否支付异常
    paid_date = db.DateTimeField()  # 支付时间
    pay_tax_deadline = db.DateTimeField()  # 支付税截至时间

    refund_entries = db.ListField(
        db.ReferenceField('OrderEntry', reverse_delete_rule=mongoengine.PULL))
    refund_amount = db.FloatField(default=0)
    is_test = db.BooleanField(default=False)

    fields_to_log = {
        'status',
        'amount',
        'coin',
        'final',
        'estimated_tax',
        'real_tax',
        'paid_tax',
        'real_shipping',
        'is_paid',
    }
    # 处理中的状态
    PROCESSING_STATUS = [ORDER_STATUS.PAYMENT_RECEIVED, ORDER_STATUS.SHIPPING]
    # 异常状态
    ABNORMAL_STATUS = [
        ORDER_STATUS.CANCELLED, ORDER_STATUS.ABNORMAL,
        ORDER_STATUS.ORDER_DELETE, ORDER_STATUS.EXPIRED, ORDER_STATUS.REFUNDED
    ]

    def __unicode__(self):
        return '%s' % self.sid

    def __str__(self):
        return '{}'.format(self.id)

    @classmethod
    def get_order_or_404(cls, order_id, check_user=True):
        try:
            order = cls.objects(id=order_id).first_or_404()
        except mongoengine.ValidationError:
            try:
                short_id = int(order_id)
            except (ValueError, TypeError):
                abort(404)
            order = cls.objects(short_id=short_id).first_or_404()

        if check_user and str(order.customer_id) != str(current_user.id):
            abort(404)

        return order

    @queryset_manager
    def commodities(doc_cls, queryset):
        return queryset.filter(order_type=ORDER_TYPE.COMMODITY,
                               status__nin=doc_cls.ABNORMAL_STATUS)

    @queryset_manager
    def transfer(doc_cls, queryset):
        return queryset.filter(order_type=ORDER_TYPE.TRANSFER,
                               status__nin=doc_cls.ABNORMAL_STATUS)

    @queryset_manager
    def processing(doc_cls, queryset):
        return queryset.filter(status__in=doc_cls.PROCESSING_STATUS)

    @queryset_manager
    def payment_pending(doc_cls, queryset):
        return queryset.filter(status=ORDER_STATUS.PAYMENT_PENDING)

    @queryset_manager
    def abnormal(doc_cls, queryset):
        return queryset.filter(
            Q(status__in=doc_cls.ABNORMAL_STATUS)
            | Q(refund_entries__0__exists=True)
            & Q(status__in=doc_cls.PROCESSING_STATUS +
                [ORDER_STATUS.RECEIVED]))

    @queryset_manager
    def received(doc_cls, queryset):
        return queryset.filter(status=ORDER_STATUS.RECEIVED)

    @queryset_manager
    def is_processing(self):
        return self.status in self.PROCESSING_STATUS

    @queryset_manager
    def is_payment_pending(self):
        return self.status == ORDER_STATUS.PAYMENT_PENDING

    @queryset_manager
    def is_abnormal(self):
        if self.status in self.ABNORMAL_STATUS:
            return True
        if self.status in self.PROCESSING_STATUS or self.status == ORDER_STATUS.RECEIVED:
            return len(self.refund_entries) > 0
        return False

    def has_refund_entries(self):
        if self.status in (self.PROCESSING_STATUS +
                           [ORDER_STATUS.RECEIVED, ORDER_STATUS.REFUNDED]):
            return len(self.refund_entries) > 0
        return False

    @property
    def tax(self):
        if self.real_tax == -1:
            return self.estimated_tax
        else:
            return self.real_tax

    @property
    def shipping(self):
        return self.cn_shipping

    @property
    def estimated_weight(self):
        return sum(
            float(entry.item_snapshot.weight) * entry.quantity
            for entry in self.entries)

    @property
    def pay_tax_remain_days(self):
        if self.pay_tax_deadline:
            time_remain = self.pay_tax_deadline.date() - datetime.date.today()
            if time_remain.days > 0:
                return time_remain.days

    @property
    def latest_logistic(self):
        attr = LogisticDetail.attr_by_log_status.get(self.status)
        if not attr:
            return None
        return max(self.logistics, key=lambda l: getattr(l.detail, attr))

    @classmethod
    def create_transfer(cls,
                        customer_id,
                        entries,
                        logistic_provider,
                        coupon_codes,
                        coin=0,
                        cash=0,
                        address=None,
                        **kwargs):
        order = cls(customer_id=customer_id,
                    entries=entries,
                    logistic_provider=logistic_provider,
                    coupon_codes=coupon_codes,
                    coin=coin,
                    cash=cash,
                    **kwargs)
        if not order.forex:
            order.forex = ForexRate.get()

        order.update_amount()
        order.reload()
        if address:
            order.set_address(address)

        order_created.send('system', order=order)

        return order

    @classmethod
    def create_from_skus(cls,
                         customer_id,
                         skus,
                         logistic_provider,
                         coupon_codes,
                         coin=0,
                         cash=0,
                         address=None,
                         **kwargs):
        entries = []
        for s in skus:
            availability = check_availability_and_update_stock(
                s['item_id'], s['sku'], s['quantity'])
            if not availability:
                return s
            spec = ItemSpec.objects(sku=s['sku']).first()
            item = Item.objects(item_id=['item_id']).first()
            entry = OrderEntry(spec=spec, item=item,
                               quantity=s['quantity']).save()
            entries.append(entry)

        order = cls(customer_id=customer_id,
                    entries=entries,
                    logistic_provider=logistic_provider,
                    coupon_codes=coupon_codes,
                    coin=coin,
                    cash=cash,
                    **kwargs)
        if not order.forex:
            order.forex = ForexRate.get()

        order.update_amount()
        order.reload()
        # 简介
        for e in order.entries:
            e.create_snapshot()

        if address:
            order.set_address(address)

        order_created.send('system', order=order)
        return order

    @classmethod
    def create(cls,
               customer_id,
               entries,
               logistic_provider,
               coupon_codes,
               coin=0,
               cash=0,
               address=None,
               **kwargs):
        order_entries = []
        for entry in entries:
            availability = check_availability_and_update_stock(
                entry.item_snapshot.item_id, entry.item_spec_snapshot.sku,
                entry.quantity)
            if not availability:
                return entry
            if isinstance(entry, (CartEntry, OrderEntry)):
                e = deepcopy(entry)
                e.__class__ = OrderEntry
                e.id = None
                order_entries.append(e.save())

        order = cls(customer_id=customer_id,
                    entries=order_entries,
                    logistic_provider=logistic_provider,
                    coupon_codes=coupon_codes,
                    coin=coin,
                    cash=cash,
                    **kwargs)
        if not order.forex:
            order.forex = ForexRate.get()

        order.update_amount()
        order.reload()
        for e in order.entries:
            e.create_snapshot()

        if address:
            order.set_address(address)

        order_created.send('system', order=order)
        return order

    @property
    def item_changed(self):
        res = False
        for e in self.entries:
            res = res and e.item_changed
            if res:
                return res
            return res

    def __get__(self, *args, **kwargs):
        order = super(Order, self).__get__(*args, **kwargs)
        if (not order.is_paid) and order.item_changed:
            order.update_entry()
            return order

    def update_entry(self):
        if self.is_paid:
            return
        map(lambda e: e.update_snapshot(), self.entries)
        self.update_amount()

    def set_address(self, addr):
        if not isinstance(addr, Address):
            addr = Address.objects(id=addr).first()
        if not addr:
            return False
        addr_snapshot = deepcopy(addr)
        addr_snapshot.id = None
        addr_snapshot.order_id = self.id
        addr_snapshot.save()
        if self.address:
            self.address.delete(w=1)
        self.address = addr_snapshot
        self.save()
        return True

    @property
    def customer(self):
        return User.objects(id=self.customer_id).first()

    def create_payment(self, ptype, trader):
        ptype = ptype.upper()
        self.update_entry()
        self.reload()
        if self.order_type != ORDER_TYPE.TRANSFER:
            is_available = self.check_entries_avaliable()
            if not is_available or self.status in [
                    'CANCELLED', 'ABNORMAL', 'ORDER_DELETED', 'EXPIRED'
            ]:
                return None

        new_payment = Payment(order=self, ptype=ptype, trader=trader).save()
        return new_payment

    def get_payment(self, ptype):
        ptype = ptype.upper()
        payments = Payment.objects(order=self,
                                   ptype=ptype).order_by('-created_at')
        paid_payments = payments.filter(status=PAYMENT_STATUS.PAID)
        if paid_payments:
            return paid_payments.first()
        else:
            return payments.first()

    @property
    def goods_payment(self):
        return self.get_payment(PAYMENT_TYPE.WITHOUT_TAX)

    @property
    def tax_payment(self):
        return self.get_payment(PAYMENT_TYPE.WITH_TAX)

    @property
    def refunds(self):
        return Refund.objects(order=self)

    def check_entries_avaliable(self):
        availability = all(
            map(lambda e: e.is_available or e.item_spec_snapshot.stock != -1,
                self.entries))
        if not availability:
            self.status = ORDER_STATUS.EXPIRED
            self.save()
        return availability

    def set_paid(self):
        if self.is_paid:
            return
        self.is_new_customer = not bool(
            Order.objects(custom_id=self.customer_id, is_paid=True))
        self.is_paid = True
        self.status = ORDER_STATUS.PAYMENT_RECEIVED
        self.paid_date = datetime.datetime.utcnow()
        self.save()
        payment_received(self)

    def update_payment(self, paid_type, paid_amount, trader):
        if paid_type == PAYMENT_TYPE.WITHOUT_TAX and not self.is_paid and self.status in [
                ORDER_STATUS.PAYMENT_PENDING, ORDER_STATUS.W
        ]:
            if paid_amount == self.final and trader == PAYMENT_TRADERS.PAYPAL:
                self.set_paid()
            elif paid_amount == float('%.2f' % (self.final * self.forex)
                                      ) and trader == PAYMENT_TRADERS.WEIXIN:
                self.set_paid()
            else:
                current_app.logger.error(
                    'error at updating payment. trader: {}; ptype: {}; amount: {} order id: {}'
                    .format(trader, paid_type, paid_amount, self.id))
                self.is_payment_abnormal = True
        else:
            current_app.logger.error(
                'error at updating payment. trader: {}; ptype: {}; amount: {};  order id: {}'
                .format(trader, paid_type, paid_amount, self.id))
            self.is_payment_abnormal = True
        self.save()

    @property
    def coin_trades(self):
        return Trade.objects(reason_id=str(self.id))

    def update_logistic_status(self):
        if self.logistics:
            log_status = map(lambda m: m.detail.status, self.logistics)
            new_status = min(log_status, key=lambda l: LOG_STATUS.index(1))
            self._change_status(new_status)

    def _change_status(self, new_status):
        if self.status == new_status:
            return
        self.status = new_status
        self.status_modified = datetime.datetime.utcnow()
        self.save()

        if new_status in LOG_STATUS:
            notification_order(self, new_status)
            order_logistic_status_changed.send('Order.Logistic.Status.Changed',
                                               order=self,
                                               new_status=new_status)
        else:
            order_status_changed.send('order_status_changed',
                                      order=self,
                                      new_status=new_status)

    def delete_order(self):
        for l in self.logistics:
            l.delete(w=1)

        for entry in self.entries:
            entry.delete(w=1)

        if self.goods_payment:
            self.goods_payment.delete(w=1)
        self.delete(w=1)

    def cancel_order(self, reason, status=None):
        """

        :param reason:
        :param status:
        :return:
        """
        for l in self.logistics:
            l.close(reason)

        self.extra = reason
        self.save()

        if not status:
            status = ORDER_STATUS.ABNORMAL
        self._change_status(status)
        for entry in self.entries:
            try:
                if entry.spec.stock != -1:
                    entry.spec.update(inc__stock=entry.quantity,
                                      set__availability=True)
                    entry.item.update(set__availability=True,
                                      set__status='MOD')

            except AttributeError:
                pass

    def update_amount(self):
        for e in self.entries:
            e.update_amount()
        cal_order_price_and_apply(self)
        self.estimated_tax = cal_order_tax(self)
        self.save()

    @property
    def sid(self):
        return self.short_id

    def to_json(self,
                include_logistic=False,
                replace_entries_to_refunded=False):
        if not self.is_paid:
            self.update_amount()
            self.reload()

        entries_json = []
        if replace_entries_to_refunded and self.has_refund_entries():
            for e in self.refund_entries:
                entries_json.append(e.to_json())
        else:
            for e in self.entries:
                entries_json.append(e.to_json())

        refund_entries_json = []
        for e in self.refund_entries:
            refund_entries_json.append(e.to_json())

        result = dict(
            id=str(self.id),
            short_id=str(self.sid),
            status=self.status,
            customer_id=str(self.customer_id),
            amount=self.amount,
            cn_shipping=self.cn_shipping,
            coin=self.coin,
            lucky_money=self.lucky_money,
            discount=self.discount,
            final=self.final,
            estimated_tax=self.estimated_tax,
            payment_status='PAID' if self.is_paid else 'UNPAID',
            payment_ref_number=[
                p.ref_number for p in Payment.objects(order=self)
            ],
            created_at=format_date(self.created_at),
            entries=entries_json,
            refund_entries=refund_entries_json,
            refund_amount=self.refund_amount,
            real_tax=self.real_tax,
        )
        if self.address:
            result.update({'address': self.address.to_json()})
        if include_logistic:
            result.update(logistics=[l.to_json() for l in self.logistics])

        return result

    def to_grouped_json(self):
        """

        :return:
        """
        res = dict(
            estimated_weight=self.estimated_weight,
            amount=self.amount,
            cn_shipping=self.cn_shipping,
            coin=self.coin,
            lucky_money=self.lucky_money,
            discount=self.discount,
            final=self.final,
            extimated_tax=self.extimated_tax,
        )
        res['sid'] = self.id
        res['status'] = self.status
        if self.address:
            res.update(dict(address=self.address.to_json()))
        return res
Exemple #17
0
class Kline(db.Document):
    '''
    ex: str 交易所
    contract: str 交易对
    open: float 开盘价
    high: float 最高价
    low: float 最低价
    close: float 收盘价
    volume: float 成交量
    count: int 成交笔数(默认不展示,有些交易所没有此项数据,若需要请在fields里添加)
    amount: float 成交额 (默认不展示,需在fields里添加上,有些交易所没有此项数据)
    freq: str 行情频率
    time: datetime 行情时间
    '''
    _id = db.StringField()
    ex = db.StringField(required=True)
    contract = db.StringField(required=True)
    open = db.FloatField(required=True)
    high = db.FloatField(required=True)
    low = db.FloatField(required=True)
    close = db.FloatField(required=True)
    volume = db.FloatField(required=True)
    count = db.FloatField(required=True, default=0)
    amount = db.FloatField(required=True, default=0)
    freq = db.StringField(required=True)
    time = db.DateTimeField(required=True)
    ctime = db.DateTimeField(required=True, default=arrow.utcnow().datetime)
    utime = db.DateTimeField(required=True, default=arrow.utcnow().datetime)

    meta = {'db_alias': 'market', 'collection': 'kline', 'strict': False}

    def to_json(self, key=True):
        if key:
            return {
                "ex": self.ex.upper(),
                "contract": self.contract.upper(),
                "open": self.open,
                "high": self.high,
                "low": self.low,
                "close": self.close,
                "volume": self.volume,
                "freq": self.freq,
                "time": arrow.get(self.time).float_timestamp,
                "ctime": arrow.get(self.ctime).float_timestamp,
            }
        else:
            return [
                arrow.get(self.time).float_timestamp,
                self.open,
                self.high,
                self.low,
                self.close,
                self.volume,
            ]

    def __repr__(self):
        return '<Kline ex:\'%s\', contract:\'%s\'>' % (self.ex, self.contract)

    @staticmethod
    def get_within(ex=None,
                   contract=None,
                   freq=None,
                   start_time=None,
                   end_time=None,
                   limit=None,
                   order=None,
                   key=True):
        '''
        获取时间区间内的数据
        :param ex:
        :param contract:
        :param freq:
        :param start_time:
        :param end_time:
        :param limit:
        :param key:
        :return:
        '''
        if contract not in ALL_CONTRACTS:
            raise Exception('error contract')

        query = Kline.objects
        if ex:
            query = query.filter(ex=ex)
        if contract:
            query = query.filter(contract=contract)
        if freq:
            query = query.filter(freq=freq)
        if start_time:
            start_time = arrow.get(start_time).datetime
            query = query.filter(time__gte=start_time)
        if end_time:
            end_time = arrow.get(end_time).datetime
            query = query.filter(time__lt=end_time)
        if order:
            query = query.order_by(order)

        data_list = query.all()
        if limit:
            data_list = data_list[:limit]

        result = []
        if data_list:
            for data in data_list:
                result.append(data.to_json(key))

        return result

    @staticmethod
    def insert_data(data,
                    update_when_exist=True,
                    update_fields=['open', 'high', 'low', 'close', 'volume']):
        '''
        新增数据
        :param data:
        :return:
        '''
        if 'ex' not in data or 'contract' not in data or 'freq' not in data or 'time' not in data:
            raise Exception('params missed')
        if data['contract'] not in ALL_CONTRACTS:
            raise Exception('error contract')

        # 检测,防止重复插入
        kline = Kline.objects(ex=data['ex'],
                              contract=data['contract'],
                              freq=data['freq'],
                              time=data['time']).first()

        if not kline:
            return Kline(**data).save()
        else:
            if not update_when_exist:
                return False

            # 只更新当天的,过去的数据不用改变,所以不用更新
            new_time = arrow.get(data['time']).datetime
            old_time = arrow.get(kline.time).datetime
            if new_time == old_time:
                update_data = dict()
                if 'open' in data and data[
                        'open'] != kline.open and 'open' in update_fields:
                    update_data['open'] = data['open']
                if 'high' in data and data[
                        'high'] != kline.high and 'high' in update_fields:
                    update_data['high'] = data['high']
                if 'low' in data and data[
                        'low'] != kline.low and 'low' in update_fields:
                    update_data['low'] = data['low']
                if 'close' in data and data[
                        'close'] != kline.close and 'close' in update_fields:
                    update_data['close'] = data['close']
                if 'volume' in data and data[
                        'volume'] != kline.volume and 'volume' in update_fields:
                    update_data['volume'] = data['volume']
                if update_data:
                    print('kline update:', data['ex'], data['contract'],
                          data['freq'], data['time'], update_data)
                    update_data['utime'] = arrow.utcnow().datetime
                    Kline.objects(_id=kline._id).update_one(**update_data)
            return True
Exemple #18
0
class Events(db.EmbeddedDocument):
    time = db.LongField()
    desc = db.StringField()
Exemple #19
0
class User(db.Document):
    """A user model.

    The :class:`User` object is only created once the user logs in for the
    first time and confirms the details of their account.

    :ivar date_created: :class:`mongoengine.fields.DateTimeField` - The date
        that this user was created.
    :ivar date_modified: :class:`mongoengine.fields.DateTimeField` - The date
        the this user was last modified.
    :ivar gplus_id: :class:`mongoengine.fields.StringField` - The Google+ ID
        for this user.  It's what we use in the Google+ authentication.
    :ivar name: :class:`mongoengine.fields.StringField` - The user's name.
    :ivar slug: :class:`mongoengine.fields.StringField` - A URL slug  their
        internal profile page.
    :ivar email: :class:`mongoengine.fields.EmailField` - The user's email
        address.
    :ivar roles: :class:`mongoengine.fields.ListField` of
        :class:`mongoengine.fields.StringField` - A list of roles that the user
        has.
    :ivar privileges: :class:`mongoengine.fields.DictField` - A dictionary of
        privileges that the user has.  Often determined soley by their
        ``user_type``.
    :ivar image_url: :class:`mongoengine.fields.URLField` - The URL of the
        profile picture for the user's profile picture.
    :ivar image: :class:`mongoengine.fields.ReferenceField` - The local image
        for the user's profile picture.
    :ivar user_type: :class:`mongoengine.fields.StringField` - The type of the
        user. Can either be ``"fake_user"``, ``"editor"``, ``"publisher"``, or
        ``"admin"``.  The selection of user type determines their
        ``privileges``.
    :ivar last_logon: :class:`mongoengine.fields.DateTimeField` - The date of
        this user's last logon.
    """

    date_created = db.DateTimeField(required=True, default=now)
    date_modified = db.DateTimeField(required=True, default=now)
    gplus_id = db.StringField(required=True, unique=True)
    name = db.StringField(required=True, max_length=510)
    slug = db.StringField(required=True,
                          max_length=510,
                          unique=True,
                          regex=SLUG_REGEX)
    email = db.EmailField(required=True, unique=True)
    roles = db.ListField(db.StringField(db_field="role"), default=list)
    privileges = db.DictField(required=True, default={})
    image_url = db.URLField()
    image = db.ReferenceField('Image')
    user_type = db.StringField(default='editor', regex=USER_TYPE_REGEX)
    last_logon = db.DateTimeField()

    # MongoEngine ORM metadata
    meta = {'allow_inheritance': True, 'indexes': ['email', 'gplus_id']}

    def can(self, privilege):
        """Returns True if the user has ``privilege``.

        :returns: True if the user has ``privilege``
        :rtype: bool
        """
        return self.privileges.get(privilege)

    def get_profile_picture(self, size=50):
        """Returns the url to the profile picture for the user.

        TODO: This method needs major fixing.  What's going on with that URL?

        :param int size: The size of the image to pass, if the size can be
            changed.

        :returns: The URL of the image.
        :rtype: str
        """
        if self.image:
            return self.image.url()
        if not self.image_url:
            # Import app in the function body to avoid importing `None` when
            # the module is first loaded.
            from app import app
            return url_for('static',
                           filename=app.config['DEFAULT_PROFILE_PICTURE'])
        if "googleusercontent.com" in self.image_url:
            return self.image_url + str(size)
        return self.image_url

    def register_login(self):
        """Update the model as having logged in."""
        self.last_logon = now()

    def clean(self):
        """Called by Mongoengine on every ``.save()`` to the object.

        Update date_modified and apply privileges shorthand notation.

        :raises: :class:`wtforms.validators.ValidationError`
        """
        self.date_modified = now()

        # Update self.privileges with one of the USER_TYPES dictionaries
        self.privileges.update(USER_TYPES[self.user_type])

        # Update the slug for the user (used in URLs)
        new_slug = self.name.lower().replace(' ', '-')
        new_slug = re.sub(r"\'|\.|\_|", "", new_slug)
        if User.objects(slug=new_slug).count() > 0:
            i = 2
            new_slug = new_slug + "-{}".format(i)
            while User.objects(slug=new_slug).count() > 0:
                i += 1
                new_slug = re.sub(r"-([0-9])*$", "-{}".format(i), new_slug)
        self.slug = new_slug

        if self.image_url and "googleusercontent.com" in self.image_url:
            self.image_url = re.sub(r"sz=([0-9]*)$", "sz=", self.image_url)

    def id_str(self):
        """The id of this object, as a string.

        :returns: The id
        :rtype: str
        """
        return str(self.id)

    def role(self):
        """Returns the role of the user, in plain English.  It is either
        ``"Admin"``, ``"Publisher"``, ``"Editor"``, or ``"Fake User"``.

        :returns: The role.
        :rtype: str
        """
        if self.can('admin'):
            return "Admin"
        if self.can('publish'):
            return "Publisher"
        if self.can('edit'):
            return "Editor"
        return "Fake User"

    def __repr__(self):
        """The representation of this user.

        :returns: The user's details.
        :rtype: str
        """
        return ('User(id=%r, name=%r, email=%r, roles=%r, privileges=%r, '
                'gplus_id=%r, date_created=%r)' %
                (self.id, self.name, self.email, self.roles, self.privileges,
                 self.gplus_id, self.date_created))

    def __unicode__(self):
        """This user, as a unicode string.

        :returns: The user encoded as a string.
        :rtype: str
        """
        if self.can('admin'):
            return '%r <%r> (Admin)' % (self.name, self.email)
        if self.can('publish'):
            return '%r <%r> (Publisher)' % (self.name, self.email)
        if self.can('edit'):
            return '%r <%r> (Editor)' % (self.name, self.email)
        else:
            return '%r <%r> (Fake User)' % (self.name, self.email)
Exemple #20
0
class DynamicRow(db.Document):
    timeStamp = db.StringField()
    motor = db.EmbeddedDocumentField(Motor)
    dataReceived = db.EmbeddedDocumentField(DataReceived)
    meta = {'collection': 'DynamicRow'}
Exemple #21
0
class User(db.Document):
    email = db.EmailField(unique=True)
    password = db.StringField(default=True)
    active = db.BooleanField(default=True)
    isAdmin = db.BooleanField(default=False)
    timestamp = db.DateTimeField(default=datetime.datetime.now())
Exemple #22
0
class Weather(db.Document):
    anaemometer = db.StringField()
    pyranometer = db.StringField()
    site = db.IntField()
    timeStamp = db.IntField()
class Rooms(db.EmbeddedDocument):
    name = db.StringField()
    controls = db.ListField(db.EmbeddedDocumentField(Control))
Exemple #24
0
class Motor(db.EmbeddedDocument):
    trackingResolution = db.IntField()
    status = db.StringField()
    cumulativeHours = db.IntField()
    current = db.FloatField()
    inclinometerAngle = db.FloatField()
class AccessGroup(db.DynamicDocument):
    type = db.StringField(max_length=10)
    name = db.StringField(max_length=80, unique=True)
    UIDs = db.ListField(db.StringField(), default=[])
    meta = {'collection': 'access_group'}
Exemple #26
0
class Led(db.EmbeddedDocument):
    power = db.StringField()
    comm = db.StringField()
    motor = db.StringField()
    mode = db.StringField()
    master = db.StringField()
class Mode(db.Document):
    name = db.StringField()
    controlData = db.EmbeddedDocumentListField(ControlData)
Exemple #28
0
class Transactions(db.Document):
    sourceAccount = db.StringField()
    destinationAccount = db.StringField()
    value = db.IntField()
    createdDate = db.DateTimeField(default=datetime.now)
Exemple #29
0
class Todo(db.Document):
    content = db.StringField(required=True, max_length=20)
    time = db.DateTimeField(default=datetime.datetime.now())
    status = db.IntField(default=0)
Exemple #30
0
class User(UserMixin, db.Document):
    user_id = db.IntField(required=True)
    user_name = db.StringField(required=True, max_length=100)
    email = db.StringField(max_length=200)
    password_hash = db.StringField(requied=True)
    timezone = db.StringField(requied=True, max_length=6)
    user_info = db.DictField(requied=True)
    role_id = db.IntField(required=True)
    confirmed = db.BooleanField(required=True, default=False)
    must_change_password = db.BooleanField(required=True, default=False)
    banned = db.BooleanField(required=True, default=False)
    suspended = db.BooleanField(required=True, default=False)
    created_time = db.DateTimeField(required=True,
                                    default=arrow.utcnow().datetime)
    updated_time = db.DateTimeField(required=True,
                                    default=arrow.utcnow().datetime)

    meta = {
        'db_alias': 'account',
        'collection': 'user',
        'allow_inheritance': True
    }

    def __init__(self, **kwargs):
        super(User, self).__init__(**kwargs)

    def save(self):
        if not self.user_id:
            self.user_id = Counter.get_id('user')
        if not self.user_info:
            self.user_info = default_user_info
        super(User, self).save()

    def to_json(self):
        return {
            "user_id": self.user_id,
            "user_name": self.user_name,
            "email": self.email,
            "timezone": self.timezone,
            "role_id": self.role_id,
            "confirmed": self.confirmed,
            "must_change_password": self.must_change_password,
            "banned": self.banned,
            "suspended": self.suspended,
            "created_time": self.created_time,
            "updated_time": self.updated_time,
        }

    @property
    def role(self):
        return Role.objects(pkid=self.role_id, enable=True).first()

    def full_name(self):
        return '%s %s' % (self.user_info['first_name'],
                          self.user_info['last_name'])

    def can(self, permission):
        return self.role is not None and self.role.permissions[
            permission] == True

    def is_admin(self):
        return self.can('administer')

    def is_active(self):
        return True

    @property
    def is_authenticated(self):
        return True

    def is_confirmed(self):
        return self.confirmed

    def is_must_change_password(self):
        return self.must_change_password

    def is_banned(self):
        return self.banned

    def is_suspended(self):
        return self.suspended

    def get_id(self):
        return str(self.user_id)

    @property
    def password(self):
        raise AttributeError('`password` is not a readable attribute')

    @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)

    def generate_confirmation_token(self, expiration=604800):
        """Generate a confirmation token to email a new user."""

        s = Serializer(current_app.config['SECRET_KEY'], expiration)
        return s.dumps({'confirm': self.user_id})

    def generate_email_change_token(self, new_email, expiration=3600):
        """Generate an email change token to email an existing user."""
        s = Serializer(current_app.config['SECRET_KEY'], expiration)
        return s.dumps({'change_email': self.user_id, 'new_email': new_email})

    def generate_password_reset_token(self, expiration=3600):
        """
        Generate a password reset change token to email to an existing user.
        """
        s = Serializer(current_app.config['SECRET_KEY'], expiration)
        return s.dumps({'reset': self.user_id})

    def confirm_account(self, token):
        """Verify that the provided token is for this user's id."""
        s = Serializer(current_app.config['SECRET_KEY'])
        try:
            data = s.loads(token)
        except (BadSignature, SignatureExpired):
            return False
        if data.get('confirm') != self.user_id:
            return False
        self.confirmed = True
        self.save()
        return True

    def change_email(self, token):
        """Verify the new email for this user."""
        s = Serializer(current_app.config['SECRET_KEY'])
        try:
            data = s.loads(token)
        except (BadSignature, SignatureExpired):
            return False
        if data.get('change_email') != self.user_id:
            return False
        new_email = data.get('new_email')
        if new_email is None:
            return False
        if self.objects(email=new_email).first() is not None:
            return False
        self.email = new_email
        db.session.add(self)
        db.session.commit()
        return True

    def reset_password(self, token, new_password):
        """Verify the new password for this user."""
        s = Serializer(current_app.config['SECRET_KEY'])
        try:
            data = s.loads(token)
        except (BadSignature, SignatureExpired):
            return False
        if data.get('reset') != self.id:
            return False
        self.password = new_password
        self.save()
        return True

    def __repr__(self):
        return '<User \'%s %s\'>' % (self.user_id, self.user_name)