def post(self): parser = CustomRequestParser() parser.add_argument('mobile', type=str, required=True, nullable=False, location='json') # 收款人的用户手机号 parser.add_argument('amount', type=int, required=True, nullable=False, location='json') parser.add_argument('security_password', type=str, required=True, nullable=False, location='json') parsed_args = parser.parse_args() user = User.query.filter(User.mobile == parsed_args['mobile']).first() if user is None: abort(400, code=1001, message={'mobile': 'user does not exist'}) if parsed_args['amount'] <= 0: abort(400, code=1003, message={'amount': 'amount <= 0'}) if not g.current_user.security_password: abort(400, code=1012, message={'security_password': '******'}) if not g.current_user.verify_security_password(parsed_args['security_password']): abort(400, code=1002, message={'security_password': '******'}) if not g.current_user.is_community_node: abort(400, code=1001, message={'current_user': '******'}) if user.is_community_node: abort(400, code=1001, message={'user': '******'}) option = Setting.get_json('general_option') community_transaction_fee_rate = option['community_transaction_fee_rate'] # exchange_amount_min = option['exchange_amount_min'] # exchange_amount_max = option['exchange_amount_max'] # # if parsed_args['amount'] < exchange_amount_min or parsed_args['amount'] > exchange_amount_max: # abort(400, code=1006, # message={'amount': 'amount < {} or amount > {}'.format(exchange_amount_min, exchange_amount_max)}) fee = decimal.Decimal(parsed_args['amount']) * decimal.Decimal(community_transaction_fee_rate) amount = decimal.Decimal(parsed_args['amount']) + decimal.Decimal(fee) assets = Assets.get_assets(g.current_user.id) detail = { 'message': '{}转给{}, 金额:{}, 手续费:{}'.format( g.current_user.mobile, user.mobile, parsed_args['amount'], fee) } if not assets.update_transaction_balance(-amount, g_assets_record_type.TRANSACTION, detail): abort(400, code=1008, message={'balance': 'current balance < {}'.format(amount)}) assets = Assets.get_assets(user.id) assets.update_total_balance(parsed_args['amount'], g_assets_record_type.TRANSACTION, detail) db.session.commit() return assets
def update_transaction_free(self): option = Setting.get_json('general_option') transaction_free_generation = option['transaction_free_generation'] transaction_free_amount = option['transaction_free_amount'] community_free_generation = option['community_free_generation'] community_free_amount = option['community_free_amount'] # 加速释放每一代 layer = 0 sponsor = self.sponsor while sponsor and layer < community_free_generation: if sponsor.is_community_node == 0 and layer < transaction_free_generation: amount = transaction_free_amount elif sponsor.is_community_node == 1: amount = community_free_amount else: amount = 0 if amount != 0: details = { 'message': '交易加速释放,交易完成者:{}, 第几代:{}'.format(self.uid, layer + 1) } assets = Assets.get_assets(sponsor.id) # amount = min(assets.total_balance, amount) if assets.update_total_balance( -amount, g_assets_record_type.ACCELERATE_FREE, details): assets.update_transaction_balance( amount, g_assets_record_type.ACCELERATE_FREE, details) layer += 1 sponsor = sponsor.sponsor
def community_check_user(user, total_balance, transaction_day_cnt, sponsor_cnt, line_cnt, line_people_cnt): assets = Assets.get_assets(user.id) if assets.grand_total_balance < total_balance: return False count = db.session.query(db.func.count(User.id)).filter( User.sponsor_id == user.id, User.continuous_buy_cnt >= transaction_day_cnt, User.active == 1).first()[0] if count < sponsor_cnt: return False q = User.query.filter(User.sponsor_id == user.id, User.active == 1).all() qualified_sum = 0 for user in q: if user.team_qualified_cnt >= line_people_cnt: qualified_sum += 1 if qualified_sum >= line_cnt: return True return False
def activate(self): from app.model.schedule_task import RegisterScheduleTask self.active = 1 task = RegisterScheduleTask(user_id=self.id) db.session.add(task) from app.model.assets import Assets assets = Assets(user_id=self.id) db.session.add(assets) db.session.flush() # 保证顺序
def update_recommend_reward(self): option = Setting.get_json('general_option') recommend_reward_amount = [ decimal.Decimal(x) for x in option['recommend_reward_amount'] ] evaluation_reward_amount = decimal.Decimal( option['evaluation_reward_amount']) # 先赠送本用户 usd_price = Currency.get_price() if usd_price == 0: abort(400, code=1002, message={'usd_price': 'usd_price is invaild'}) # amount = evaluation_reward_amount / usd_price amount = 1000 assets = Assets.get_assets(self.id) details = {'message': u'完成评测奖励'} assets.update_total_balance(amount, g_assets_record_type.EVALUATION, details) # 再赠送每一代推荐 layer = 0 layer_max = len(recommend_reward_amount) sponsor = self.sponsor while sponsor and layer < layer_max: details = { 'message': '被推荐人:{}, 第几代:{}'.format(self.uid, layer + 1) } if sponsor.state == g_user_state_type.EVALUATION: assets = Assets.get_assets(sponsor.id) assets.update_total_balance(recommend_reward_amount[layer], g_assets_record_type.SPONSOR, details) layer += 1 sponsor = sponsor.sponsor
def confirm_order_process(): order_list = ConfirmOrder.query.filter(ConfirmOrder.status == g_confirm_order_status.UNPROCESSED).all() for order in order_list: change = ConfirmOrder.query.filter( ConfirmOrder.id == order.id, ConfirmOrder.status == g_confirm_order_status.UNPROCESSED).update( dict(status=g_confirm_order_status.PROCESSED)) if not change: continue detail = {'message': '挂单交易'} assets = Assets.get_assets(order.buy_user_id) assets.update_community_today_balance(order.amount, g_assets_record_type.BUY, detail) # 用于计算一个买卖周期 order.buy_user.buy_order_cnt += 1 if order.sell_user.buy_order_cnt > 0: order.sell_user.buy_order_cnt -= 1 option = Setting.get_json('general_option') buy_sell_free_amount = option['buy_sell_free_amount'] buy_sell_rate = decimal.Decimal(option['buy_sell_rate']) fee = order.amount * buy_sell_rate amount = buy_sell_free_amount - fee detail = { 'message': '成功买卖各一单,释放数量:{}, 单数量:{}, 扣除手续费:{}'.format( buy_sell_free_amount, order.amount, fee) } assets = Assets.get_assets(order.sell_user_id) if assets.update_total_balance(-buy_sell_free_amount, g_assets_record_type.BUY_SELL_FREE, detail): assets.update_transaction_balance(amount, g_assets_record_type.BUY_SELL_FREE, detail) sell_user = order.sell_user sell_user.update_today_have_transaction() sell_user.update_transaction_free() currency = Currency.get_currency() currency.update_transaction_cnt() db.session.commit()
def post(self): parser = CustomRequestParser() parser.add_argument('amount', type=int, required=True, nullable=False, location='json') parser.add_argument('security_password', type=str, required=True, nullable=False, location='json') parsed_args = parser.parse_args() if parsed_args['amount'] <= 0: abort(400, code=1003, message={'amount': 'amount <= 0'}) if not g.current_user.security_password: abort(400, code=1012, message={'security_password': '******'}) if not g.current_user.verify_security_password(parsed_args['security_password']): abort(400, code=1002, message={'security_password': '******'}) option = Setting.get_json('general_option') exchange_amount_min = option['exchange_amount_min'] exchange_amount_max = option['exchange_amount_max'] if parsed_args['amount'] % exchange_amount_min > 0: abort(400, code=1001, message={'amount': 'the amount must be a multiple of {}'.format(exchange_amount_min)}) # 用于计算今天兑换的数量 str_time = datetime.datetime.now().strftime('%Y-%m-%d') sum_amount = db.session.query(db.func.sum(AssetsBalanceRecord.delta_amount)).filter( db.func.date_format(AssetsBalanceRecord.created_at, '%Y-%m-%d') == str_time, AssetsBalanceRecord.user_id == g.current_user.id, AssetsBalanceRecord.record_type == g_assets_record_type.EXCHANGE, AssetsBalanceRecord.assets_type == g_assets_type.COMMUNITY).first()[0] sum_amount = sum_amount if sum_amount is not None else 0 if sum_amount + parsed_args['amount'] > exchange_amount_max: abort(400, code=1006, message={ 'amount': 'already amount {} + current amount {} > {}'.format(sum_amount, parsed_args['amount'], exchange_amount_max)}) assets = Assets.get_assets(g.current_user.id) detail = {'message': '兑换'} if not assets.update_transaction_balance(-parsed_args['amount'], g_assets_record_type.EXCHANGE, detail): abort(400, code=1008, message={'balance': 'current balance < {}'.format(parsed_args['amount'])}) assets.update_community_balance(parsed_args['amount'], g_assets_record_type.EXCHANGE, detail) db.session.commit() return assets
def check_order_process(): option = Setting.get_json('general_option') change_time = int(option['order_status_change_time']) # 接单后不打款 q = db.session.query(Order).filter(Order.id == MatchOrder.sell_order_id, MatchOrder.created_at < datetime.datetime.now() - datetime.timedelta(hours=change_time), Order.status == g_order_status.MATCH).all() for order in q: match_order = order.match_order if match_order is None: continue rows_changed = Order.query.filter( Order.side == g_order_side.SELL, Order.number == match_order.sell_number, Order.status == g_order_status.MATCH).update(dict(status=g_order_status.CANCELLED)) if not rows_changed: continue detail = {'message': "超时不打款,卖单号:{},买单号:{},买方手机:{}".format(match_order.sell_number, match_order.buy_number, match_order.buy_user.mobile)} rows_changed = Order.query.filter( Order.side == g_order_side.BUY, Order.number == match_order.buy_number, Order.status == g_order_status.MATCH).update(dict(status=g_order_status.CANCELLED)) if rows_changed: assets = Assets.get_assets(order.user_id) assets.update_community_balance(order.amount, g_assets_record_type.SELL, detail) else: order.status = g_order_status.MATCH db.session.commit()
def delete(self, order_number): # parser = reqparse.RequestParser() # parser.add_argument('security_password', type=str, required=True, nullable=False, location='json') # parsed_args = parser.parse_args() # # if not g.current_user.security_password: # abort(400, code=1012, message={'security_password': '******'}) # if not g.current_user.verify_security_password(parsed_args['security_password']): # abort(400, code=1002, message={'security_password': '******'}) order = Order.query.filter(Order.side == g_order_side.SELL, Order.number == order_number, Order.user_id == g.current_user.id).first() if order is None: abort(400, code=1001, message={'order_number': 'order does not exist'}) detail = {'message': '卖家取消挂单'} rows_changed = Order.query.filter_by( user_id=g.current_user.id, side=g_order_side.SELL, number=order_number, status=g_order_status.PENDING).update( dict(status=g_order_status.CANCELLED)) if rows_changed == 1: assets = Assets.get_assets(order.user_id) assets.update_community_balance(order.amount, g_assets_record_type.SELL, detail) else: abort(400, code=1002, message={'status': 'status != g_order_status.PENDING'}) db.session.commit() return order
def put(self, order_number): parser = reqparse.RequestParser() parser.add_argument('status', type=int, required=True, choices=(g_order_status.CONFIRMED, g_order_status.CANCELLED), location='json') parser.add_argument('side', type=int, default=g_order_side.SELL, choices=(g_order_side.BUY, g_order_side.SELL), location='json') parsed_args = parser.parse_args() order = Order.query.filter(Order.number == order_number, Order.side == parsed_args['side']).first() if order is None: abort(400, code=1001, message={'order_id': 'order does not exist'}) if (order.status == g_order_status.PENDING or order.status == g_order_status.MATCH or g_order_status.PAID) and \ parsed_args['status'] == g_order_status.CANCELLED: if parsed_args['side'] == g_order_side.SELL: match_order = MatchOrder.query.filter( MatchOrder.sell_number == order.number).first() else: match_order = MatchOrder.query.filter( MatchOrder.buy_number == order.number).first() if match_order is None: rows_changed = Order.query.filter( db.or_(Order.status == g_order_status.PENDING, Order.status == g_order_status.MATCH, Order.status == g_order_status.PAID), Order.number == order.number, Order.side == parsed_args['side']).update( dict(status=g_order_status.CANCELLED)) if not rows_changed: abort(400, code=1002, message={'status': 'status not allow'}) else: rows_changed = Order.query.filter( db.or_(Order.status == g_order_status.PENDING, Order.status == g_order_status.MATCH, Order.status == g_order_status.PAID), Order.side == g_order_side.SELL, Order.number == match_order.sell_number).update( dict(status=g_order_status.CANCELLED)) if not rows_changed: abort(400, code=1002, message={'status': 'status not allow'}) rows_changed = Order.query.filter( db.or_(Order.status == g_order_status.PENDING, Order.status == g_order_status.MATCH, Order.status == g_order_status.PAID), Order.side == g_order_side.BUY, Order.number == match_order.buy_number).update( dict(status=g_order_status.CANCELLED)) if not rows_changed: abort(400, code=1002, message={'status': 'status not allow'}) if parsed_args['side'] == g_order_side.SELL: detail = {'message': '后台取消挂单释放'} assets = Assets.get_assets(order.user_id) assets.update_community_balance(order.amount, g_assets_record_type.SELL, detail) elif order.status == g_order_status.PAID and parsed_args[ 'status'] == g_order_status.CONFIRMED: if parsed_args['side'] == g_order_side.SELL: match_order = MatchOrder.query.filter( MatchOrder.sell_number == order.number).first() else: match_order = MatchOrder.query.filter( MatchOrder.buy_number == order.number).first() if match_order is None: abort(400, code=1001, message={'order_id': 'mach order does not exist'}) ret, reason = Order.confirm_order(match_order) if not ret: abort(400, code=reason['code'], message=reason['message']) confirm_order = reason db.session.add(confirm_order) else: message = { g_order_status.CANCELLED: g_order_status.PENDING, g_order_status.CONFIRMED: g_order_status.PAID } abort(400, code=1002, message={ 'status': 'status != %d' % message[parsed_args['status']] }) db.session.commit() return order
def get(self): assets = Assets.get_assets(g.current_user.id) return assets
def generate_order_process(): option = Setting.get_json('general_option') sell_people = option['sell_people'] buy_people = option['buy_people'] sell_count = option['sell_count'] buy_count = option['buy_count'] str_time = datetime.datetime.now().strftime('%Y-%m-%d') order_list = SellOrder.query.filter(SellOrder.status == g_sell_order_status.UNPROCESSED).all() buy_list = BuyOrder.query.filter(BuyOrder.status == g_buy_order_status.UNPROCESSED).all() order_list.extend(buy_list) order_list = sorted(order_list, key=lambda e: e.created_at) for item in order_list: logging.info('Order side:{}, id:{}'.format(item.side, item.id)) if item.side == g_order_side.SELL: if item.user.transaction_level != g_user_transaction_level.ULTIMATE: order = Order.query.filter(Order.user_id == item.user_id, Order.side == g_order_side.BUY, Order.status == g_order_status.CONFIRMED).first() if not order: # 提示语"该用户从未购买过" error_details = dict(code=1001, message={'user': '******'}) item.details = json.dumps(error_details) item.status = g_sell_order_status.FAILED db.session.commit() continue order_people = db.session.query(Order.user_id).filter( Order.created_at >= str_time, Order.side == g_order_side.SELL, Order.status != g_order_status.CANCELLED).count() order_people = order_people if order_people else 0 if order_people >= sell_people: # 提示语"当日入场单量已满" error_details = dict(code=1003, message={'count': 'count >= {}'.format(sell_people)}) item.details = json.dumps(error_details) item.status = g_sell_order_status.FAILED db.session.commit() continue count = db.session.query(db.func.count(SellOrder.id)).filter( db.func.date_format(SellOrder.created_at, '%Y-%m-%d') == str_time, SellOrder.user_id == item.user_id, SellOrder.status == g_sell_order_status.PROCESSED).first()[0] count = count if count else 0 if count >= sell_count: # 提示语"今天卖出的单数已满" error_details = dict(code=1006, message={'user': '******'.format(sell_count)}) item.details = json.dumps(error_details) item.status = g_sell_order_status.FAILED db.session.commit() continue detail = {'message': '挂单冻结'} assets = Assets.get_assets(item.user_id) if not assets.update_community_balance(-item.amount, g_assets_record_type.SELL, detail): # 提示语"余额不足" if assets.community_today_balance > 0: error_details = dict(code=1007, message={ 'order': 'please tomorrow to sell, today buy balance:{}'.format( assets.community_today_balance)}) else: error_details = dict(code=1008, message={'balance': 'current balance < {}'.format(item.amount)}) item.details = json.dumps(error_details) item.status = g_sell_order_status.FAILED db.session.commit() continue item.status = g_sell_order_status.PROCESSED else: order_people = db.session.query(Order.user_id).filter( Order.created_at >= str_time, Order.side == g_order_side.BUY, Order.status != g_order_status.CANCELLED).count() order_people = order_people if order_people else 0 if order_people >= buy_people: # 提示语"当日入场单量已满" error_details = dict(code=1003, message={'count': 'count >= {}'.format(buy_people)}) item.details = json.dumps(error_details) item.status = g_sell_order_status.FAILED db.session.commit() continue # 用于计算今天买入的单数 count = db.session.query(db.func.count(BuyOrder.id)).filter( db.func.date_format(BuyOrder.created_at, '%Y-%m-%d') == str_time, BuyOrder.user_id == item.user_id, BuyOrder.status == g_buy_order_status.PROCESSED).first()[0] count = count if count else 0 if count >= buy_count: # 提示语"今天买入的单数已满" error_details = dict(code=1006, message={'user': '******'.format(buy_count)}) item.details = json.dumps(error_details) item.status = g_sell_order_status.FAILED db.session.commit() continue item.status = g_buy_order_status.PROCESSED order = Order(created_at=item.created_at, user_id=item.user_id, side=item.side, amount=item.amount, number=item.number) db.session.add(order) db.session.commit()
def settlement_handler(): option = Setting.get_json('general_option') community_node_cnt = option['community_node_cnt'] community_total_balance = option['community_total_balance'] community_transaction_day_cnt = option['community_transaction_day_cnt'] community_sponsor_cnt = option['community_sponsor_cnt'] community_line_cnt = option['community_line_cnt'] community_line_people_cnt = option['community_line_people_cnt'] # 更新连续购买天数 User.update_continuous_buy_cnt() User.query.update(dict(team_qualified_cnt=0)) # TODO 测试是否可以写成一个update Assets.query.filter(Assets.community_today_balance > 0).update( dict(community_balance=Assets.community_balance + Assets.community_today_balance)) Assets.query.update(dict(community_today_balance=0)) # 筛选出合格用户,并更新每个团队合格用户人数 q = User.query.filter( User.continuous_buy_cnt >= community_transaction_day_cnt, User.active == 1).all() for user in q: user.update_team_qualified_cnt() count = db.session.query(db.func.count(User.id)).filter( User.is_community_node == 1, User.active == 1).first()[0] user_q = db.session.query(User).filter( User.id == Assets.user_id, Assets.grand_total_balance >= community_total_balance[0], User.is_community_node == 0).all() for user in user_q: ret = 0 if count < community_node_cnt[0]: ret = DailySettlement.community_check_user( user, community_total_balance[0], community_transaction_day_cnt, community_sponsor_cnt[0], community_line_cnt[0], community_line_people_cnt) elif count < community_node_cnt[1]: ret = DailySettlement.community_check_user( user, community_total_balance[1], community_transaction_day_cnt, community_sponsor_cnt[1], community_line_cnt[1], community_line_people_cnt) elif count < community_node_cnt[2]: ret = DailySettlement.community_check_user( user, community_total_balance[2], community_transaction_day_cnt, community_sponsor_cnt[2], community_line_cnt[2], community_line_people_cnt) else: pass if ret: user.update_is_community_node() count += 1 if not count: return # 计算节点分红 community_dividend_rate = decimal.Decimal( option['community_dividend_rate']) currency = Currency.get_currency() amount = currency.today_transaction_amount * community_dividend_rate / count q = User.query.filter(User.is_community_node == 1, User.active == 1).all() detail = { 'message': '社区节点分红, 当天交易量:{}, 分红比例:{}, 社区节点数量:{}'.format( currency.today_transaction_amount, community_dividend_rate, count) } for user in q: assets = Assets.get_assets(user.id) assets.update_total_balance(amount, g_assets_record_type.DIVIDEND, detail) currency.clear_today_transaction_amount()