def mine(): """用户攒钱概况. :reqheader Authorization: OAuth 2.0 Bearer Token :status 200: 返回 :class:`~jupiter.views.api.v1.savings.ProfileSchema` """ profile_schema = ProfileSchema(strict=True) profile = SavingsManager(request.oauth.user.id_) if request.user_agent.app_info.version <= parse_version('1.0'): profile.refresh_profile() conditional_for([ unicode(profile.user_id), unicode(profile.on_account_invest_amount), unicode(profile.daily_profit), unicode(profile.total_profit), unicode(profile.total_orders), ]) sxb_account = None sxb_vendor = Vendor.get_by_name(Provider.sxb) if sxb_vendor: sxb_account = NewAccount.get(sxb_vendor.id_, request.oauth.user.id_) profile.has_sxb_account = True if sxb_account else False return jsonify(success=True, data=profile_schema.dump(profile).data)
def get_recommend_products(user=None): recommend_products = product_pool() from .product import get_products all_product = get_products() if not user: return wrapped_product(all_product, recommend_products['high_priority_products'], recommend_products) is_new_saving_user = SavingsManager(user.id_).is_new_savings_user if is_new_saving_user: return wrapped_product(all_product, recommend_products['high_priority_products'], recommend_products) sxb_products = recommend_products['medium_priority_products'] is_sxb_on_sale = [p.is_on_sale for p in sxb_products] if any(is_sxb_on_sale): return wrapped_product(all_product, sxb_products, recommend_products) xm_products = recommend_products['low_priority_products'] is_xm_in_stock = [p.is_on_sale for p in xm_products] if any(is_xm_in_stock): return wrapped_product(all_product, xm_products, recommend_products) return wrapped_product(all_product, recommend_products['medium_priority_products'], recommend_products)
def init(): if not for_anonymous and not g.user: return redirect(url_for('accounts.login.login', next=request.path)) g.yx_account = YixinAccount.get_by_local(g.user.id) if g.user else None g.zw_account = ZhiwangAccount.get_by_local( g.user.id) if g.user else None g.xm_account = XMAccount.get_by_local(g.user.id) if g.user else None g.savings_manager = SavingsManager(g.user.id_) if g.user else None
def collect_user_tags(user_id): from core.models.hoard.manager import SavingsManager tags = set() # 判断用户是否是攒钱用户 sm = SavingsManager(user_id) if not sm.is_new_savings_user: tags.add('savings') return tags
def asset_profile(): """用户资产概况 :reqheader Authorization: OAuth 2.0 Bearer Token :reqheader If-None-Match: 客户端缓存的 ETag :resheader ETag: 客户端可缓存的 ETag :status 304: 客户端缓存未过期, 无需返回数据 :status 200: 返回 :class:`.AssetProfile` """ savings_manager = SavingsManager(request.oauth.user.id_) hoard_total = savings_manager.total_invest_amount hoard_daily_profit = savings_manager.daily_profit hoard_yesterday_profit = savings_manager.yesterday_profit wallet_total = 0 wallet_yesterday_profit = 0 wallet_account = WalletAccount.get_by_local_account(request.oauth.user, zhongshan) if wallet_account: dashboard = UserDashboard.today(wallet_account) wallet_total = dashboard.balance wallet_yesterday_profit = dashboard.latest_profit_amount profile = { 'total_amount': float(hoard_total) + float(wallet_total), 'total_yesterday_profit': float(hoard_yesterday_profit) + float(wallet_yesterday_profit), 'hoard_amount': hoard_total, 'hoard_daily_profit': hoard_daily_profit, 'hoard_yesterday_profit': hoard_yesterday_profit, 'wallet_amount': wallet_total, 'wallet_yesterday_profit': wallet_yesterday_profit } conditional_for([ unicode(profile['total_amount']), unicode(profile['total_yesterday_profit']), unicode(profile['hoard_amount']), unicode(profile['hoard_daily_profit']), unicode(profile['hoard_yesterday_profit']), unicode(profile['wallet_amount']), unicode(profile['wallet_yesterday_profit']) ]) schema = AssetProfile() return jsonify(success=True, data=schema.dump(profile).data)
def mine(): # 攒钱助手 savings_manager = SavingsManager(g.user.id_) savings_products = ZhiwangProduct.get_all() vendor = Vendor.get_by_name(Provider.sxb) sxb_products = Product.get_products_by_vendor_id(vendor.id_) xm_products = XMFixedDuedayProduct.get_all() # 零钱包 wallet_dashboard = PublicDashboard.today() wallet_account = WalletAccount.get_by_local_account(g.user, zhongshan) if wallet_account: wallet_profile = UserDashboard.today(wallet_account) wallet_has_transaction = bool( WalletTransaction.get_ids_by_account(wallet_account.id_)) else: wallet_profile = None wallet_has_transaction = False # 规划书 report = Report.get_latest_by_plan_id(g.plan.id) if g.plan else None if not (report and report.status >= REPORT_STATUS.interdata): return render_template('/mine/center_unplanned.html', **locals()) if int(report.formula_ver) < int(FORMULA_VER): regen_log(report, 'start regenerate inter data') cal_intermediate_data(report, force=True, log=regen_log) report.update_formula_ver(FORMULA_VER) regen_log(report, 'success regenerate inter data FV:%s' % report.formula_ver) inter_data = report.inter_data locals().update(inter_data) cur_path = 'center' return render_template('/mine/center.html', **locals())
def products(): """攒钱助手待售产品. :query partner: 可选参数,按合作方支持情况限制返回结果. 目前可为: - ``"zw"`` 指旺 - ``"xm"`` 新米 :reqheader Authorization: OAuth 2.0 Bearer Token :reqheader If-None-Match: 客户端缓存的 ETag :resheader ETag: 客户端可缓存的 ETag :status 304: 客户端缓存未过期, 无需返回数据 :status 200: 返回 :class:`.ProductSchema` 列表 """ from .products.consts import sale_display_text product_schema = ProductSchema(strict=True, many=True) partners = frozenset(request.args.getlist('partner')) profile = SavingsManager(request.oauth.user.id_) profile.refresh_profile() services = [] def product_sale_status_to_text(product): is_early_morning_product = isinstance( product, (XMProduct, ZhiwangWrappedProduct)) if product.in_stock: return sale_display_text['on_sale'] elif product.is_taken_down: if is_early_morning_product: return sale_display_text['early_morning_off_sale'] return sale_display_text['late_morning_off_sale'] elif product.is_either_sold_out: if is_early_morning_product: return sale_display_text['early_morning_sold_out'] return sale_display_text['late_morning_sold_out'] if 'zw' in partners and zhiwang_fdb_product_on_switch.is_enabled: zw_services = [] for s in ZhiwangProduct.get_all(): if s.product_type is ZhiwangProduct.Type.fangdaibao: zw_services.append(s) elif s.product_type is ZhiwangProduct.Type.classic: if s.profit_period['min'] not in (OriginProfitPeriod( 90, 'day'), OriginProfitPeriod( 180, 'day'), OriginProfitPeriod( 270, 'day'), OriginProfitPeriod(365, 'day')): zw_services.append(s) zw_services.sort(key=attrgetter('annual_rate')) ZhiwangProfile.add(request.oauth.user.id_) for zw_service in zw_services: product_text = product_sale_status_to_text(zw_service) if product_text: zw_service.button_display_text, zw_service.button_click_text = product_text zw_service.is_able_purchased = zw_service.in_stock zw_service.introduction = '' zw_service.title = '' zw_service.activity_title = '' zw_service.activity_introduction = '' zw_service._total_amount = 0 zw_service.agreement = url_for('savings.landing.agreement_zhiwang', _external=True) zw_service.annotations = ZhiwangProduct.get_product_annotations( g.coupon_manager, zw_service) services.extend(zw_services) if 'xm' in partners: xm_products = [s for s in XMProduct.get_all()] xm_products.sort(key=attrgetter('annual_rate')) XMProfile.add(request.oauth.user.id_) for xm_product in xm_products: product_text = product_sale_status_to_text(xm_product) if product_text: xm_product.button_display_text, xm_product.button_click_text = product_text xm_product.is_able_purchased = xm_product.in_stock xm_product.introduction = '' xm_product.title = '' xm_product.activity_title = '' xm_product.activity_introduction = '' xm_product._total_amount = 0 xm_product.agreement = url_for('savings.landing.agreement_xinmi', _external=True) xm_product.annotations = XMProduct.get_product_annotations( g.coupon_manager, xm_product) services.extend(xm_products) product_data = product_schema.dump(services).data for product in product_data: product.update({'is_newcomer': False}) all_product_data = [] if 'sxb' in partners: from .products.sxb import get_sxb_products product_schema = SxbProductSchema(strict=True, many=True) sxb_products = get_sxb_products(request.oauth.user.id_) services.extend(sxb_products) sxb_father_products = [ p for p in sxb_products if p.kind is Product.Kind.father ] sxb_father_product_data = product_schema.dump(sxb_father_products).data if SavingsManager(request.oauth.user.id_).is_new_savings_user: sxb_child_products = [ p for p in sxb_products if p.kind is Product.Kind.child ] sxb_child_product_data = product_schema.dump( sxb_child_products).data for product in sxb_child_product_data: product.update({'is_newcomer': True}) all_product_data.extend(sxb_child_product_data) all_product_data.extend(sxb_father_product_data) all_product_data.extend(product_data) conditional_for(json.dumps(all_product_data)) return jsonify(success=True, data=all_product_data)
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)