Beispiel #1
0
    def be_member(self, userid, customer_id, src=MemDefine.MEMBER_SRC_WX):
        ''' 成为会员

        如果是新会员将返回1, 否则返回0

        '''
        now = int(time.time())
        try:
            with get_connection_exception('qf_mchnt') as db:
                cardno = getid()
                db.insert('member',
                          values={
                              'id': cardno,
                              'userid': userid,
                              'customer_id': customer_id,
                              'num': 0,
                              'txamt': 0,
                              'last_txdtm': 0,
                              'ctime': now,
                              'utime': now
                          })
                self._cardno = cardno

                db.insert('member_tag',
                          values={
                              'id': getid(),
                              'userid': userid,
                              'customer_id': customer_id,
                              'src': src,
                              'ctime': now,
                              'utime': now
                          })
        except:
            return 0
        return 1
Beispiel #2
0
    def POST(self):
        userid = int(self.user.userid)
        actv = None
        with get_connection('qf_mchnt') as db:
            actv = db.select_one(
                    'member_actv',
                    where= {
                        'userid': userid,
                        'type': MemDefine.ACTV_TYPE_PRIVI
                    })
        if actv:
            raise ParamError('已经创建过特权活动了.')


        content = self.validator.data['content']
        content = remove_emoji(content)
        if str_len(content) > 80:
            raise ParamError('活动内容不超过80字')

        now = int(time.time())
        data = {}
        data['id'] = getid()
        data['title'] = ''
        data['content'] = content
        data['userid'] = userid
        data['status'] = MemDefine.ACTV_STATUS_ON
        data['ctime'] = data['utime'] =  now
        data['start_time'] = now
        data['expire_time'] = now + 20 * 365 * 24 * 3600
        data['type'] = MemDefine.ACTV_TYPE_PRIVI
        with get_connection('qf_mchnt') as db:
            db.insert('member_actv', data)

        return self.write(success({}))
Beispiel #3
0
    def _trans_input(self):
        d = {k: v.strip() for k, v in self.req.input().iteritems()}
        r = {}
        price = d.get('price', 10)
        num = d.get('num', 0)
        type = d.get('type', 1)
        content = d.get('content', '')
        title = d.get('title', '')
        if not all(map(is_valid_int, (price, num, type))):
            raise ParamError('参数不正确')
        r['price_code'] = ''
        r['promo_code'] = ''
        r['goods_code'] = 'message'
        r['userid'] = int(self.user.ses.get('userid', ''))

        # 商品价格和名称
        total = int(price) * int(num)
        r['total_amt'] = r['txamt'] = total
        r['goods_name'] = '短信营销'
        r['price'] = price
        r['num'] = num
        r['type'] = type
        r['content'] = content
        r['id'] = getid()
        r['title'] = title

        return r
Beispiel #4
0
    def POST(self):
        userid = int(self.user.userid)

        # 商户付费状态
        groupid = self.get_groupid()
        mchnt = get_payinfo_ex(userid,
                service_code='card_actv', groupid=groupid)
        if not mchnt:
            add_free_ex(userid, service_code='card_actv', groupid=groupid)
        elif str(mchnt['expire_time']) <= time.strftime(DATETIME_FMT):
            if mchnt['status'] == MCHNT_STATUS_FREE:
                raise ParamError('免费体验已经到期了哦')
            if mchnt['status'] == MCHNT_STATUS_NORMAL:
                raise ParamError('付费已经到期了哦')

        # 能否创建集点活动
        self.allow_create(userid)

        actv = self.validator.data

        # 适用门店
        d = self.req.input()
        actv['mchnt_id_list'] = self.get_mchnt_id_list(
                d.get('mchnt_id_list', '').strip().split(','))
        actv['userid'] = userid
        actv['goods_name'] = remove_emoji(actv.get('goods_name'))
        if not 1 <= str_len(actv['goods_name']) <= 8:
            raise ParamError('商品名长度是1至8位')

        if actv['goods_amt'] <= 0:
            raise ParamError('商品价格应大于0')

        actv['start_time'] = actv.get('start_time') or time.strftime(DT_FMT)
        if not(is_valid_date(actv['start_time']) and
               is_valid_date(actv['expire_time'])):
            raise ParamError('活动时间格式不合法')
        if actv['start_time'] > actv['expire_time']:
            raise ParamError('开始时间应该小于结束时间')
        actv['start_time'] = str_to_tstamp(actv['start_time'], DT_FMT)
        actv['expire_time'] = str_to_tstamp(actv['expire_time'], DT_FMT) + 86399

        if actv['exchange_pt'] not in range(1, 11):
            raise ParamError('暂不只支持该兑换集点的活动')

        if actv['obtain_amt'] <= 0:
            raise ParamError('集点条件大于0')

        if actv['obtain_limit'] < 0:
            raise ParamError('一次交易获取的最多集点应该大于0')

        actv['id'] = getid()
        actv['ctime'] = actv['utime'] = int(time.time())
        actv['status'] = ACTV_STATUS_NORMAL

        with get_connection_exception('qf_mchnt') as db:
            db.insert('card_actv', actv)

        return self.write(success({'id': actv['id']}))
Beispiel #5
0
    def add_tag(self, userid, customer_id, tag, src):
        '''
        如果是在连锁店认证, 将会对所有连锁店进行授权
        '''
        userids = [
            int(userid),
        ]
        big_uid = self.get_big_uid(userid) or userid
        userids = self.get_link_ids(big_uid) or []
        userids.append(int(big_uid))

        with get_connection('qf_mchnt') as db:
            now = int(time.time())
            exist_user = db.select(table='member_tag',
                                   where={
                                       'userid': ('in', userids),
                                       'customer_id': customer_id,
                                   },
                                   fields='userid') or []
            exist_userids = [i['userid'] for i in exist_user]
            log.debug(exist_userids)
            # 更新已有的
            if exist_userids:
                db.update(table='member_tag',
                          values={
                              tag: 1,
                              'utime': now,
                          },
                          where={
                              tag: 0,
                              'userid': ('in', exist_userids),
                              'customer_id': customer_id,
                          })

            insert_data = []
            for i in userids:
                if i not in exist_userids:
                    insert_data.append({
                        'id': getid(),
                        'userid': userid,
                        'customer_id': customer_id,
                        'src': src,
                        'ctime': now,
                        'utime': now,
                        tag: 1
                    })
            if insert_data:
                db.insert_list('member_tag',
                               values_list=insert_data,
                               other='ON DUPLICATE KEY UPDATE %s=1' % tag)

            return True

        return False
Beispiel #6
0
 def _insert(userids, expire_time):
     if not userids: return
     with get_connection_exception('qf_mchnt') as db:
         status = d.get('status') or MCHNT_STATUS_NORMAL
         now = int(time.time())
         indata = [{
             'id': getid(),
             'userid': i,
             'goods_code': d['goods_code'],
             'status': status,
             'expire_time': expire_time,
             'content': d['content'],
             'ctime': now,
             'utime': now
         } for i in userids]
         db.insert_list('recharge', indata)
Beispiel #7
0
    def POST(self):
        d = self._trans_input()
        now = int(time.time())

        # 插入渠道
        with get_connection('qf_mchnt') as db:
            promo_data = {
                'id': getid(),
                'userid': d['userid'],
                'balance': 0,
                'status': PROMO_STATUS['normal'],
                'ctime': now,
                'utime': now
            }
            db.insert('promo', promo_data)
        return self.write(success({}))
Beispiel #8
0
    def update_mchnt(self, userid, goods_codes, months):
        st = datetime.date.today()
        with get_connection('qf_mchnt') as db:
            # 获取当前的信息
            infos = db.select(table='recharge',
                              where={
                                  'goods_code': ('in', goods_codes),
                                  'userid': userid
                              }) or []
            infos = {i['goods_code']: i for i in infos}

            for code in goods_codes:
                try:
                    if code in infos:
                        exptm = infos[code]['expire_time']
                        if str(exptm) > time.strftime(DATETIME_FMT):
                            st = datetime.date(year=exptm.year,
                                               month=exptm.month,
                                               day=exptm.day)
                    end = str_to_tstamp(
                        str(future(st, months=months)) + ' 23:59:59',
                        DATETIME_FMT)

                    if code in infos:
                        db.update(table='recharge',
                                  values={
                                      'expire_time': end,
                                      'utime': int(time.time()),
                                      'status': 2
                                  },
                                  where={
                                      'userid': userid,
                                      'goods_code': code
                                  })
                    else:
                        db.insert(table='recharge',
                                  values={
                                      'id': getid(),
                                      'userid': userid,
                                      'goods_code': code,
                                      'status': 2,
                                      'expire_time': end,
                                      'ctime': int(time.time()),
                                      'utime': int(time.time()),
                                  })
                except:
                    log.warn('更新消费者有效期失败:%s' % traceback.format_exc())
Beispiel #9
0
    def update(self, userid, customer_id):
        try:
            with get_connection_exception('qf_mchnt') as db:
                # 会员来源(支付)
                PAY_SRC = 1
                data = {'card': 1}
                data['utime'] = int(time.time())
                update_result = db.update('member_tag',
                                          values=data,
                                          where={
                                              'userid': userid,
                                              'customer_id': customer_id,
                                          })

                if not update_result:
                    data['id'] = getid()
                    data['ctime'] = int(time.time())
                    data['src'] = PAY_SRC
                    data['userid'] = userid
                    data['customer_id'] = customer_id
                    db.insert('member_tag', values=data)
        except:
            pass
Beispiel #10
0
    def tidy_codes(self, codes, customer, actv):
        cur_num = customer['cur_pt'] / actv['exchange_pt']
        codes_num = len(codes)

        # 若兑换卡数相同
        if cur_num == codes_num:
            return codes

        now = int(time.time())
        # 当前卡数大于实际卡数
        if cur_num < codes_num:
            cancel_num = codes_num - cur_num
            cancel_codes = [codes[i]['id'] for i in range(cancel_num)]
            with get_connection('qf_mchnt') as db:
                db.update(table='exchange_record',
                          values={
                              'utime': now,
                              'status': CODE_STATUS_CANCEL
                          },
                          where={'id': ('in', cancel_codes)})
            return codes[cancel_num:]

        # 实际卡数大于当前卡数
        with get_connection('qf_mchnt') as db:
            records = db.select(table='exchange_record',
                                fields='code, status',
                                where={'activity_id': actv['id']})
        allcodes = defaultdict(set)
        # allcodes:
        # 0: 所有code 1: 已兑换 2:创建优惠码 3:已撤销
        for i in records or []:
            allcodes[0].add(i['code'])
            allcodes[i['status']].add(i['code'])

        add_num = cur_num - codes_num
        choose, allchoose = [], set(range(1, 10000))
        if 9999 - len(allcodes[0]) > add_num:
            choose = random.sample(list(allchoose - allcodes[0]), add_num)
        else:
            try:
                choose = random.sample(
                    list(allchoose - allcodes[CODE_STATUS_CREATE]), add_num)
            except:
                log.error('兑换码不够,error:%s' % traceback.format_exc())

        data = []
        for code in choose:
            data.append({
                'id': getid(),
                'code': code,
                'userid': actv['userid'],
                'ctime': now,
                'utime': now,
                'customer_id': customer['customer_id'],
                'activity_id': actv['id'],
                'status': CODE_STATUS_CREATE
            })
        if data:
            codes.extend(data)
            with get_connection('qf_mchnt') as db:
                db.insert_list('exchange_record', data)

        return codes
Beispiel #11
0
    def _cancel(self, d):
        now = int(time.time())
        with get_connection('qf_mchnt') as db:
            # 获取集点记录
            pt = db.select_one(table='pt_record',
                               where={
                                   'out_sn': d['orig_out_sn'],
                                   'type': PT_RECORD_GET
                               })
            if not pt:
                return
            actv_id = pt['activity_id']

            where = {'activity_id': actv_id, 'customer_id': d['customer_id']}

            # 获取消费者信息
            member = db.select_one('member_pt', where=where)
            if not member:
                raise ParamError('消费者信息不存在')

            # 撤销集点
            cancel_pt = min(pt['pts'], member['cur_pt'])

            # 插入pt_record
            try:
                pidata = deepcopy(d)
                pidata['id'] = getid()
                pidata['ctime'] = pidata['utime'] = now
                pidata['activity_id'] = actv_id
                pidata['type'] = PT_RECORD_CANCEL
                pidata['pts'] = cancel_pt
                db.insert('pt_record', pidata)
            except:
                log.warn('insert error: %s' % traceback.format_exc())
                return

            card_id = member['id']
            if not cancel_pt:
                return {
                    'cancel_pt': cancel_pt,
                    'activity_id': actv_id,
                    'card_id': card_id
                }

            # 更新消费者的集点
            try:
                mem_updata = {
                    'txamt': DBFunc('txamt-%s' % d['txamt']),
                    'total_amt': DBFunc('total_amt-%s' % d['total_amt']),
                    'total_pt': DBFunc('total_pt-%d' % cancel_pt),
                    'cur_pt': DBFunc('cur_pt-%d' % cancel_pt),
                    'utime': now
                }
                db.update('member_pt', mem_updata, where)
            except:
                log.debug('更新消费者集点信息失败, %s' % traceback.format_exc())
            else:
                # 更新活动信息
                try:
                    ucwhere = {'id': actv_id, 'total_pt': ('>=', cancel_pt)}
                    ucdata = {
                        'total_pt': DBFunc('total_pt-%d' % cancel_pt),
                        'utime': now
                    }
                    db.update('card_actv', ucdata, ucwhere)
                except:
                    log.debug('%s' % traceback.format_exc())

                return {
                    'cancel_pt': cancel_pt,
                    'activity_id': actv_id,
                    'card_id': card_id
                }
Beispiel #12
0
    def _query(self, d):
        rcard, rcustomer, overdue = {}, {}, 0
        now = int(time.time())
        # 获取生效的集点活动
        with get_connection('qf_mchnt') as db:
            rcard = db.select_one(
                'card_actv',
                where={
                    'userid': self.get_userid_condition(d['userid']),
                    'expire_time': ('>=', now),
                    'start_time': ('<', now)
                },
                fields=('id, start_time, expire_time, status, goods_name,'
                        'goods_amt, exchange_pt, obtain_amt, obtain_limit,'
                        'statement'),
                other='order by ctime desc')
            # 暂无生效的集点活动
            if not rcard:
                return None, None, 0

        # 商户过期信息
        overdue = adjust_payinfo_ex(
            userid=d['userid'],
            service_code='card_actv',
            groupid=self.get_groupid(userid=d['userid']))['overdue']

        with get_connection('qf_mchnt') as db:
            # 消费者信息
            customer_info = db.select_one('member_pt',
                                          where={
                                              'activity_id': rcard['id'],
                                              'customer_id': d['customer_id']
                                          }) or {}

            # 若商户过期
            if overdue:
                # 若是新消费者或者老商户且已经兑换过礼品,
                # 则不能继续集点活动了
                if (not customer_info or (not customer_info['cur_pt']
                                          and customer_info['total_pt'])):
                    return None, None, overdue

            # 返回的消费者信息
            rcustomer['cur_pt'] = customer_info.get('cur_pt') or 0
            rcustomer['is_new'] = CardBase.is_new_card(d['userid'],
                                                       d['customer_id'],
                                                       d['src'])
            rcustomer['diff_obtain_amt'] = max(
                rcard['obtain_amt'] - d['txamt'], 0)
            rcustomer['card_id'] = customer_info.get('id')
            obtain_pts = min(d['txamt'] / rcard['obtain_amt'],
                             rcard['obtain_limit'] or sys.maxint)
            rcustomer['obtain_pts'] = obtain_pts
            rcustomer['exchange'] = rcustomer['cur_pt'] / rcard['exchange_pt']

            # 插入pt_record
            # 插入失败即代表已领取过集点
            is_obtain = False
            try:
                # 若满足条件
                if not rcustomer['diff_obtain_amt']:
                    fields = [
                        'userid', 'customer_id', 'out_sn', 'txamt', 'total_amt'
                    ]
                    pt_indata = {field: d[field] for field in fields}
                    pt_indata['ctime'] = pt_indata['utime'] = now
                    pt_indata['activity_id'] = rcard['id']
                    pt_indata['type'] = PT_RECORD_GET
                    pt_indata['id'] = getid()
                    pt_indata['pts'] = obtain_pts

                    db.insert('pt_record', pt_indata)
            except:
                is_obtain = True

            # 若未领取集点
            if not is_obtain:
                try:
                    # 新集点卡消费者
                    if not customer_info:
                        m = {
                            field: d[field]
                            for field in
                            ['userid', 'customer_id', 'txamt', 'total_amt']
                        }
                        if not obtain_pts:
                            m['txamt'] = m['total_amt'] = 0

                        rcustomer['card_id'] = m['id'] = getid()
                        m['activity_id'] = rcard['id']
                        m['ctime'] = m['utime'] = now
                        m['cur_pt'] = m['total_pt'] = obtain_pts

                        db.insert('member_pt', m)

                    # 有集点的老客户
                    elif obtain_pts:
                        umwhere = {
                            'activity_id': rcard['id'],
                            'customer_id': d['customer_id']
                        }
                        umdata = {
                            'txamt': DBFunc('txamt+%s' % d['txamt']),
                            'total_amt':
                            DBFunc('total_amt+%s' % d['total_amt']),
                            'total_pt': DBFunc('total_pt+%d' % obtain_pts),
                            'cur_pt': DBFunc('cur_pt+%d' % obtain_pts),
                            'utime': now
                        }
                        db.update('member_pt', umdata, umwhere)

                except:
                    log.debug('更新消费者集点信息失败, %s' % traceback.format_exc())
                else:
                    rcustomer['cur_pt'] += obtain_pts
                    # 获取到集点, 更新活动统计信息
                    if obtain_pts:
                        try:
                            ucwhere = {'id': rcard['id']}
                            ucdata = {
                                'total_pt': DBFunc('total_pt+%d' % obtain_pts),
                                'utime': now
                            }
                            db.update('card_actv', ucdata, ucwhere)
                        except:
                            log.debug(traceback.format_exc())

                    # 延后跟新member_tag
                    gevent.spawn(self.update, d['userid'], d['customer_id'])

            # 活动信息
            rcard['id'] = str(rcard['id'])
            rcard['start_time'] = str_to_tstamp(str(rcard['start_time']))
            rcard['expire_time'] = str_to_tstamp(str(rcard['expire_time']))

            # 消费者
            org_pt, now_pt = rcustomer['cur_pt'] - obtain_pts, rcustomer[
                'cur_pt']
            rcustomer['add_exchange'] = (now_pt / rcard['exchange_pt'] -
                                         org_pt / rcard['exchange_pt'])
            rcustomer['diff_exchange'] = max(
                rcard['exchange_pt'] -
                rcustomer['cur_pt'] % rcard['exchange_pt'], 0)

        return rcard, rcustomer, overdue
Beispiel #13
0
    def POST(self):
        userid = self.user.userid

        # 验证兑换码
        code = self.req.input().get('code')
        de_code = hids.decode(code)
        if not de_code:
            raise ParamError('兑换码不存在')
        cb_id = de_code[0]

        # 获取红包绑定信息和活动信息
        cb_info = {}
        act_id = ''
        with get_connection_exception('qf_marketing') as db:
            cb_info = db.select_one(table='coupon_bind', where={'id': cb_id})

            if not cb_info:
                raise ParamError('兑换码不存在')

            act_id = cb_info.get('activity_id')

            if not act_id:
                raise ParamError('查询活动信息失败')

        amt = cb_info.get('amt')

        start_time = cb_info.get('start_time')
        expire_time = cb_info.get('expire_time')

        status = cb_info.get('status')
        coupon_mchnt_id = cb_info.get('mchnt_id')
        coupon_rule_id = cb_info.get('coupon_rule_id')

        now = datetime.datetime.now()
        if not (start_time < now < expire_time):
            raise ParamError('不在活动时间内')
        if status != COUPON_STATUS_BIND:
            raise ParamError('这张消费券不能使用了!')

        if not coupon_mchnt_id:
            mchnt_id_list = []
            mchnt_id_json = ''
            with get_connection('qf_marketing') as db:
                mchnt_id_json = db.select_one(
                    fields='mchnt_id_list',
                    where={'coupon_rule_id': coupon_rule_id})

            if not mchnt_id_json:
                raise ParamError('查询可使用商户列表失败')

            mchnt_id_list = json.loads(mchnt_id_json)

            if not (str(userid) in mchnt_id_list):
                raise ParamError('该消费券不能在该店铺使用')
        if int(coupon_mchnt_id) != int(userid):
            raise ParamError('该消费券不能在该店铺使用')

        # 使用红包
        coas = CouponOperateArgs()
        coas.coupon_code = cb_info.get('coupon_code')
        coas.src = cb_info.get('src')
        coas.type = COUPON_STATUS_USE
        coas.trade_amt = int(amt)
        coas.customer_id = str(cb_info.get('customer_id'))
        coas.out_sn = str(getid())
        coas.content = '交易使用消费券'
        coas.mchnt_id = userid

        try:
            thrift_callex(config.QF_MARKETING_SERVERS, QFMarketing,
                          'coupon_use', coas)
        except:
            log.warn(traceback.format_exc())
            raise ThirdError('使用红包失败')

        return self.write(success({}))
Beispiel #14
0
    def POST(self):
        d = {k: v.strip() for k, v in self.req.input().iteritems()}

        # 查找商户信息
        username = d.get('mobile') or d.get('username', '')
        user = None
        with get_connection('qf_core') as db:
            if '@' in username:
                where = {'auth_user.email': username}
            else:
                where = {'auth_user.username': username}
            user = db.select_join_one(
                table1='auth_user',
                table2='profile',
                on={'auth_user.id': 'profile.userid'},
                where=where,
                fields=('auth_user.id as userid, auth_user.state, '
                        'auth_user.password, profile.groupid'))
        if not user:
            raise ParamError('商户不存在')

        # 开通的服务
        goods_codes = set([])
        # 0渠道 1直营
        code_idx = int(user['groupid'] in config.QF_GROUPIDS)
        for i in d.get('goods_code', 'card').split(','):
            if i in config.PROMO_GOODS_DICT:
                goods_codes.add(config.PROMO_GOODS_DICT[i][code_idx])
        if not goods_codes:
            raise ParamError('未选中服务')

        # 月份
        price_code = d.get('price_code', 'month')
        months = int(price_code.strip('month') or 1)

        # 推广码
        promo_code = d.get('promo_code', '')
        with get_connection('qf_mchnt') as db:
            promo_info = db.select_join_one(
                'promo_code',
                'promo',
                'inner',
                on={'promo.userid': 'promo_code.userid'},
                where={'promo_code.code': promo_code},
                fields=(
                    'promo.userid, promo.balance, promo.status as pstatus, '
                    'promo.num, promo_code.type, promo_code.use_limit, '
                    'promo_code.use_num, promo_code.status as pcstatus'
                )) or {}
        if not promo_info:
            raise ParamError('推广码不存在')
        if promo_info['pcstatus'] != PROMO_CODE_STATUS['normal']:
            raise ParamError('该推广码状态不对')
        if promo_info['pstatus'] != PROMO_CODE_STATUS['normal']:
            raise ParamError('该渠道状态不对')
        if promo_info['type'] == PROMO_CODE_TYPE['balance']:
            raise ParamError('暂不支持余额码')

        # 检查使用次数
        if ((promo_info['use_num'] + len(goods_codes)) >
            (promo_info['use_limit'] or sys.maxint)):
            raise ParamError('你的开通码已经超过使用次数')

        now = int(time.time())
        # 更新promo
        with get_connection_exception('qf_mchnt') as db:
            db.update(table='promo',
                      values={
                          'num': DBFunc('num - %d' % len(goods_codes)),
                          'utime': now,
                      },
                      where={'userid': promo_info['userid']})

        # 更新promo_code
        with get_connection_exception('qf_mchnt') as db:
            db.update(table='promo_code',
                      values={
                          'use_num': DBFunc('use_num + %s' % len(goods_codes)),
                          'utime': now
                      },
                      where={'code': promo_code})

        # 插入promo_record
        with get_connection_exception('qf_mchnt') as db:
            db.insert(table='promo_record',
                      values={
                          'id': getid(),
                          'userid': promo_info['userid'],
                          'mchntid': user['userid'],
                          'promo_code': promo_code,
                          'service_code': price_code,
                          'amt': 0,
                          'promo_amt': 0,
                          'content': d.get('goods_code', 'card'),
                          'ctime': now,
                      })

        # 更新商户付费信息
        self.update_mchnt(user['userid'], goods_codes, months)

        return success({})