def test_profile_attrs(self): profile = HoardProfile.add(self.local_account.id) assert profile.plan_amount == 0 profile.plan_amount = 10000 profile = HoardProfile.get(self.local_account.id) assert profile.plan_amount == 10000 assert profile.creation_time <= datetime.datetime.now()
def test_create_profile(self): profile = HoardProfile.get(self.local_account.id) assert profile is None profile = HoardProfile.add(self.local_account.id) assert profile.account_id == self.local_account.id # add again profile = HoardProfile.add(self.local_account.id) assert profile.account_id == self.local_account.id profile = HoardProfile.get(self.local_account.id) assert profile.account_id == self.local_account.id
def order_status(order_id, new_status): """Edits the status of specific order.""" if new_status in remote_statuses(): new_status = new_status.decode(sys.stdin.encoding) else: status_list = ', '.join(remote_statuses()) bcolors.fail('status must be one of %s' % status_list) return order = HoardOrder.get(order_id) if not order: bcolors.fail('order not found') return profile = HoardProfile.get(order.user_id) matched_index = [ index for index, order_info in enumerate(profile.person_account_info) if order_info['finOrderNo'] == order.fin_order_id ] if not matched_index: bcolors.fail('failed') return account_info = list(profile.person_account_info) account_info[matched_index[0]]['finOrderStatus'] = unicode(new_status) profile.person_account_info = account_info bcolors.success('done')
def __init__(self, user_id): self.user_id = user_id self.yx_profile = HoardProfile.get(user_id) self.zw_profile = ZhiwangProfile.get(user_id) self.xm_profile = XMProfile.get(user_id) from core.models.hoarder.profile import HoarderProfile self.hoarder_profile = HoarderProfile(user_id)
def update_savings_amount(): if not g.user: abort(401) form = PlanAmountForm() if not form.validate(): return jsonify(r=False, error='\n'.join(chain(*form.errors.values()))) profile = HoardProfile.add(g.user.id) profile.plan_amount = form.data['amount'] return jsonify(r=True)
def hoard_yrd_payment_tracking(order_id): """同步用户宜人贷订单支付状态""" from core.models.hoard import HoardOrder, HoardProfile from core.models.hoard.profile import fetch_account_info, clear_account_info_cache order = HoardOrder.get(order_id) # take account info fetch as payment status sync trick profile = HoardProfile.add(order.user_id) clear_account_info_cache(order.user_id) fetch_account_info(profile) order = HoardOrder.get(order_id) rsyslog.send('%s\t%s' % (order_id, order.status), tag='yixin_payment_track') if not order.is_success and not order.is_failure: raise WorkerTaskError(hoard_yrd_payment_tracking.tube)
def record(): cur_path = 'record' yx_profile = HoardProfile.add(g.user.id_) zw_profile = ZhiwangProfile.add(g.user.id_) if not yx_profile and not zw_profile: return redirect(url_for('savings.landing.index')) filtered = bool(request.args.get('filter')) yx_orders = yx_profile.orders(filter_due=filtered) zw_mixins = zw_profile.mixins(filter_due=filtered) records = yx_orders + zw_mixins records = sorted(records, key=lambda x: x[0].creation_time, reverse=True) return render_template('savings/record.html', records=records, filter_due=filtered, cur_path=cur_path)
def orders(user_alias): """Lists all orders of specific user.""" user = Account.get_by_alias(user_alias) if not user: bcolors.fail('user not found') return profile = HoardProfile.get(user.id) if not profile: bcolors.fail('profile not initialized') return for order, _, status in profile.orders(): data = [ order.id_, order.creation_time, round(order.order_amount, 2), order.service.p2pservice_name, status, ] print(u'\t'.join(map(unicode, data)))
def hoard_yrd_exiting_checker(order_id): """确认宜人贷订单转出状态.""" from core.models.hoard import HoardOrder, HoardProfile from core.models.hoard.profile import clear_account_info_cache order = HoardOrder.get(order_id) profile = HoardProfile.get(order.user_id) orders = profile.orders() if order.fetch_status(orders) == u'已转出': order.mark_as_exited() elif order.fetch_status(orders) == u'已结束': order.mark_as_exited() else: clear_account_info_cache(order.user_id) orders = profile.orders() if order.fetch_status(orders) == u'已转出': order.mark_as_exited() if order.fetch_status(orders) == u'已结束': order.mark_as_exited()
def hoard_yrd_sms_sender(order_id): """宜人贷转出订单发送到期短信""" from core.models.sms import ShortMessage from core.models.sms.kind import savings_order_exited_sms from core.models.hoard import HoardOrder, HoardProfile from core.models.hoard.profile import clear_account_info_cache order = HoardOrder.get(order_id) user = Account.get(order.user_id) profile = HoardProfile.get(order.user_id) if not user.has_mobile(): return # 更新订单最新信息 clear_account_info_cache(order.user_id) orders = profile.orders() profit = order.fetch_profit_until(datetime.date.today(), orders) # 发送短信 sms = ShortMessage.create(user.mobile, savings_order_exited_sms, order_amount=int(order.order_amount), profit=str(round_half_up(profit, 2))) sms.send_async()
def orders(): """用户已有订单. :reqheader Authorization: OAuth 2.0 Bearer Token :reqheader If-None-Match: 客户端缓存的 ETag :resheader ETag: 客户端可缓存的 ETag :status 304: 客户端缓存未过期, 无需返回数据 :status 200: 返回 :class:`.YixinOrderSchema` 、`.XinmiOrderSchema` 或 `.ZhiwangOrderSchema` 列表 :query: 可选参数,按订单请求数限制返回结果. 目前可为: - ``"offset"`` 开始条数 - ``"count"`` 每页数量 - ``"only_due"`` 展示攒钱中的订单 """ yixin_order_schema = YixinOrderSchema(strict=True, many=True) zhiwang_order_schema = ZhiwangOrderSchema(strict=True, many=True) xm_order_schema = XinmiOrderSchema(strict=True, many=True) offset = request.args.get('offset', type=int, default=0) count = request.args.get('count', type=int, default=20) only_due = request.args.get('only_due', type=bool, default=False) order_data = [] yixin_profile = HoardProfile.add(request.oauth.user.id_) yixin_orders = [] for order, order_info, order_status in yixin_profile.orders( filter_due=only_due): order._coupon = None order._coupon_benefit = None order._order_status = order_status order._status_color = ORDER_STATUS_COLOR_MAP.get( order_status, '#9B9B9B') order._due_date = arrow_parse(order_info['frozenDatetime']).date() if order_status == u'确认中': order._confirm_desc = u'支付成功后1-3工作日' else: order._confirm_desc = order_info['startCalcDate'] yixin_orders.append(order) order_data.extend(yixin_order_schema.dump(yixin_orders).data) zhiwang_profile = ZhiwangProfile.add(request.oauth.user.id_) zhiwang_orders = [] for order, asset in zhiwang_profile.mixins(filter_due=only_due): order._display_status = asset.display_status if asset else order.display_status order._status_color = ORDER_STATUS_COLOR_MAP.get( order._display_status, '#9B9B9B') order._due_date = order.due_date.date() if order.display_status == u'处理中': order._confirm_desc = u'支付成功后第二个工作日' else: order._confirm_desc = order.start_date.date() zhiwang_orders.append(order) order_data.extend(zhiwang_order_schema.dump(zhiwang_orders).data) xm_profile = XMProfile.add(request.oauth.user.id_) xm_orders = [] for order, asset in xm_profile.mixins(filter_due=only_due): order._display_status = asset.display_status if asset else order.display_status order._status_color = ORDER_STATUS_COLOR_MAP.get( order._display_status, '#9B9B9B') order._due_date = order.due_date.date() if order.display_status == u'处理中': order._confirm_desc = u'支付成功后第二个工作日' else: order._confirm_desc = order.start_date.date() xm_orders.append(order) order_data.extend(xm_order_schema.dump(xm_orders).data) if only_due: order_data = sorted(order_data, key=itemgetter('due_date')) else: order_data = sorted(order_data, key=itemgetter('created_at'), reverse=True) order_data = order_data[offset:offset + count] conditional_for( u'{0}#{1}#{2}'.format(o['uid'], unicode(o['status']), o['status_text']) for o in order_data) return jsonify(success=True, data=order_data)
def hoard_yrd_order_syncronizer(account_id): """宜人贷订单每日定时同步""" from core.models.hoard.profile import HoardProfile, fetch_account_info profile = HoardProfile.get(account_id) fetch_account_info(profile)
def get_savings_users(cls): return HoardProfile.get_savings_users().union( ZhiwangProfile.get_savings_users())
def orders(): if not g.user: abort(401) limit = int(request.args.get('limit', 0)) filtered = bool(request.args.get('filter')) info = {} savings_records = [] yx_profile = HoardProfile.add(g.user.id_) zw_profile = ZhiwangProfile.add(g.user.id_) xm_profile = XMProfile.add(g.user.id_) yx_orders = yx_profile.orders(filter_due=filtered) zw_mixins = zw_profile.mixins(filter_due=filtered) xm_mixins = xm_profile.mixins(filter_due=filtered) placebo_order_ids = PlaceboOrder.get_ids_by_user(g.user.id_) placebo_orders = PlaceboOrder.get_multi(placebo_order_ids) if filtered: placebo_orders = [ o for o in placebo_orders if o.status is not PlaceboOrder.Status.exited ] placebo_mixins = [(order, ) for order in placebo_orders] records = yx_orders + zw_mixins + xm_mixins + placebo_mixins if filtered: records = sorted(records, key=lambda x: x[0].due_date) else: records = sorted(records, key=lambda x: x[0].creation_time, reverse=True) saving_manager = SavingsManager(g.user.id_) info['plan_amount'] = yx_profile.plan_amount info['on_account_invest_amount'] = round_half_up( saving_manager.on_account_invest_amount, 2) info['fin_ratio'] = round_half_up(saving_manager.fin_ratio, 2) info['daily_profit'] = round_half_up(saving_manager.daily_profit, 2) info['total_profit'] = round_half_up(saving_manager.total_profit, 2) limit = limit if 0 < limit < len(records) else len(records) for record_info in records[:limit]: data = dict() base_record = record_info[0] exit_type = u'到期自动转回银行卡' if base_record.provider is yirendai: order, order_info, order_status = record_info rebates = HoardRebate.get_by_order_pk(order.id_) data['annual_rate'] = order.service.expected_income data['frozen_time'] = '%s 个月' % order.service.frozen_time data['order_status'] = order_status data['savings_money'] = order_info['investAmount'] data['invest_date'] = order_info['investDate'] data['exit_type'] = exit_type if order_info[ 'exitType'] == u'退回到划扣银行卡' else order_info['exitType'] if rebates: data['rebates'] = HoardRebate.get_display(rebates) if order_status == u'确认中': data['interest_start_date'] = u'攒钱后1-3工作日' else: data['interest_start_date'] = order_info['startCalcDate'] if order_status == u'已转出': data['income_amount'] = u'%s 元' % order_info['incomeAmount'] else: data['expect_income_amount'] = u'%s 元' % order_info[ 'expectedIncomeAmount'] data['due_date'] = order.due_date.strftime('%Y-%m-%d') if order.bankcard: data['bankcard'] = u'%s (%s)' % ( order.bankcard.bank_name, order.bankcard.display_card_number) elif base_record.provider is zhiwang: order, asset = record_info data['annual_rate'] = round_half_up(order.actual_annual_rate, 2) if order.profit_period.unit == 'day': data['frozen_time'] = '%s 天' % order.profit_period.value elif order.profit_period.unit == 'month': data['frozen_time'] = '%s 个月' % order.profit_period.value else: raise ValueError('invalid unit %s' % order.profit_period.unit) data[ 'order_status'] = asset.display_status if asset else order.display_status if order.profit_hikes: data['hikes'] = { h.kind.label: h.display_text for h in order.profit_hikes } data['savings_money'] = int(order.amount) data['invest_date'] = unicode(order.creation_time.date()) data['exit_type'] = exit_type data['interest_start_date'] = order.start_date.strftime('%Y-%m-%d') if asset and asset.status == ZhiwangAsset.Status.redeemed: data['income_amount'] = u'%s 元' % round_half_up( asset.current_interest, 2) else: # 尽可能显示已加息收益 # FIXME (tonyseek) 这个做法太粗暴,有赖于资产的更新 if order.asset: expect_interest = order.asset.expect_interest else: expect_interest = order.expect_interest data['expect_income_amount'] = u'%s 元' % round_half_up( expect_interest, 2) data['due_date'] = order.due_date.strftime('%Y-%m-%d') data['contract_url'] = url_for( 'savings.zhiwang.asset_contract', asset_no=asset.asset_no) if asset else '' if asset and asset.bankcard: # 指旺回款卡以资产的银行卡为准,可能会与订单中的不一致 data['bankcard'] = u'%s (%s)' % ( asset.bankcard.bank.name, asset.bankcard.display_card_number) elif base_record.provider is placebo: if base_record.status is PlaceboOrder.Status.failure: continue order = base_record profit_amount = order.calculate_profit_amount() profit_amount_text = u'%s 元' % round_half_up(profit_amount, 2) if base_record.status is PlaceboOrder.Status.exited: data['income_amount'] = profit_amount_text else: data['expect_income_amount'] = profit_amount_text data['annual_rate'] = round_half_up(order.profit_annual_rate, 2) data['frozen_time'] = order.profit_period.display_text data['order_status'] = order.status.display_text data['order_type'] = u'体验金' data['spring_festival'] = spring_promotion_switch.is_enabled data['savings_money'] = int(order.amount) data['invest_date'] = unicode(order.start_date) data['due_date'] = unicode(order.due_date.date()) data['bankcard'] = u'%s (%s)' % ( order.bankcard.bank.name, order.bankcard.display_card_number) elif base_record.provider is xmpay: order, asset = record_info data['annual_rate'] = round_half_up(order.actual_annual_rate, 2) if order.profit_period.unit == 'day': data['frozen_time'] = '%s 天' % order.profit_period.value elif order.profit_period.unit == 'month': data['frozen_time'] = '%s 个月' % order.profit_period.value else: raise ValueError('invalid unit %s' % order.profit_period.unit) data[ 'order_status'] = asset.display_status if asset else order.display_status if order.profit_hikes: data['hikes'] = { h.kind.label: h.display_text for h in order.profit_hikes } data['savings_money'] = int(order.amount) data['invest_date'] = unicode(order.creation_time.date()) data['exit_type'] = exit_type data['interest_start_date'] = order.start_date.strftime('%Y-%m-%d') if asset and asset.status == XMAsset.Status.redeemed: data['income_amount'] = u'%s 元' % round_half_up( asset.current_interest, 2) else: # 尽可能显示已加息收益 if order.asset: expect_interest = order.asset.expect_interest else: expect_interest = order.expect_interest data['expect_income_amount'] = u'%s 元' % round_half_up( expect_interest, 2) # 尽量使用第三方返回的到期日期。 if order.asset: data['due_date'] = order.asset.interest_end_date.strftime( '%Y-%m-%d') else: data['due_date'] = order.due_date.strftime('%Y-%m-%d') data['contract_url'] = url_for( 'savings.xinmi.asset_contract', asset_no=asset.asset_no) if asset else '' if asset and asset.bankcard: # 投米回款卡以资产的银行卡为准,可能会与订单中的不一致 data['bankcard'] = u'%s (%s)' % ( asset.bankcard.bank_name, asset.bankcard.display_card_number) savings_records.append(data) return jsonify(r=True, records=savings_records, info=info)
def initialize_profile(): # disables the landing page g.hoard_profile = HoardProfile.add(g.user.id_)