def test_savings_recommend_product_with_all_sold_out( mock_get_order_amount_by_user, mock_get_total_orders, mock_has_bought_newcomer_product, client, oauth_token, oauth_client): headers = { 'X-Client-ID': oauth_client.client_id, 'X-Client-Secret': oauth_client.client_secret } client.load_token(oauth_token) # 买过新手标,随心攒售罄,365天售罄,环境准备 mock_get_order_amount_by_user.return_value = 1 mock_get_total_orders.return_value = 1 mock_has_bought_newcomer_product.return_value = True vendor = Vendor.get_by_name(Provider.sxb) sxb_products = SXBProduct.get_products_by_vendor_id(vendor.id_) for sxb in sxb_products: sxb.go_off_sale() # 访问路由,查找推荐产品 r = client.get(get_testurl_v2(testing_urls['recommend']), headers=headers) # 对比推荐产品,必须为随心攒 assert r.status_code == 200 assert r.data['success'] is True assert r.data['data']['wallet'] != [] wallet = r.data['data']['wallet'][0] vendor = Vendor.get_by_name(Provider.sxb) sxb_products = SXBProduct.get_products_by_vendor_id(vendor.id_) product_schema_assert(wallet, str(sxb_products[1].id_))
def sxb_product(sqlstore, redis, app): vendor = Vendor.get_by_name(Provider.sxb) if vendor is None: vendor = Vendor.add(Provider.sxb.value, 'sxb') product = Product.get_by_remote_id(vendor.id_, ProductConsts.SXB_VENDOR_PRODUCT_ID[0]) if product is None: def add_product(product_info): start_sell_date, end_sell_date = check_available_for_product( product_info) Product.add_or_update( vendor.id_, product_info.product_id, product_info.name, product_info.quota, product_info.total_quota, product_info.today_quota, product_info.total_amount, product_info.total_buy_amount, product_info.min_redeem_amount, product_info.max_redeem_amount, product_info.day_redeem_amount, product_info.add_year_rate, product_info.remark, Product.Type.unlimited, product_info.min_amount, product_info.max_amount, product_info.return_rate_type, product_info.return_rate, product_info.effect_day_type, product_info.effect_day, product_info.effect_day_unit, product_info.is_redeem, start_sell_date, end_sell_date) for i in range(len(ProductConsts.SXB_PRODUCT_INFO)): product_info = ProductConsts.SXB_PRODUCT_INFO[ ProductConsts.SXB_VENDOR_PRODUCT_ID[i]] add_product(Obj(product_info)) sxb_products = Product.get_products_by_vendor_id(vendor.id_) for p in sxb_products: if p.is_taken_down: p.go_on_sale() if p.remote_id == ProductConsts.SXB_VENDOR_PRODUCT_ID[0]: product = p return product
def xm_product(sqlstore, redis): vendor = Vendor.get_by_name(Provider.xm) if vendor is None: vendor = Vendor.add(Provider.xm.value, 'xm') product = XMProduct.get(ProductConsts.XINMI_PRODUCT_ID) if product is None: def add_product(product): start_sell_date, end_sell_date = check_available_for_product( product) Product.add_or_update(vendor.id_, product.product_id, product.name, float(product.quota), float(product.total_amount), float(product.total_amount), float(product.total_amount), 0, 0, 0, 0, 0, product.remark, Product.Type.classic, product.min_amount, product.max_amount, 1, product.return_rate, 1, 1, 1, Product.RedeemType.auto.value, start_sell_date, end_sell_date, product.expire_period, product.expire_period_unit) add_product(Obj(ProductConsts.XINMI_PRODUCT_INFO)) xm_products = Product.get_products_by_vendor_id(vendor.id_) for p in xm_products: if p.is_taken_down: p.go_on_sale() product = XMProduct.add(ProductConsts.XINMI_PRODUCT_INFO) return product
def test_savings_recommend_product_with_sold_out( mock_get_order_amount_by_user, mock_get_total_orders, mock_has_bought_newcomer_product, mock_check_is_inhouse, client, oauth_token, oauth_client, xm_product): headers = { 'X-Client-ID': oauth_client.client_id, 'X-Client-Secret': oauth_client.client_secret } client.load_token(oauth_token) # 买过新手标,随心攒售罄,环境准备 vendor = Vendor.get_by_name(Provider.sxb) sxb_products = SXBProduct.get_products_by_vendor_id(vendor.id_) for sxb in sxb_products: sxb.go_off_sale() mock_check_is_inhouse.return_value = True mock_get_order_amount_by_user.return_value = 1 mock_get_total_orders.return_value = 1 mock_has_bought_newcomer_product.return_value = True # 访问路由,查找推荐产品 r = client.get(get_testurl_v2(testing_urls['recommend']), headers=headers) # 对比推荐产品,必须为365天 assert r.status_code == 200 assert r.data['success'] is True assert r.data['data']['hoarder'] != [] hoarder = r.data['data']['hoarder'][0] product_schema_assert(hoarder, str(xm_product.product_id))
def init_product(self): self.init_vendor() vendor_id = Vendor.get_by_name(Provider.sxb).id_ remote_id = '2015122217504424733' name = '随心宝测试产品01' quota = 1000.0 total_quota = 200000.0 today_quota = 10000.0 total_amount = 3000000.0 total_buy_amount = 10000.0 min_redeem_amount = 1000.0 max_redeem_amount = 10000.0 day_redeem_amount = 1000.0 interest_rate_hike = 0.001 description = 'Test...' product_type = Product.Type.unlimited min_amount = 100 max_amount = 10000 rate_type = 3 rate = 0.083 effect_day_condition = 'C' effect_day = 1 effect_day_unit = '3' redeem_type = Product.RedeemType.user.value start_sell_date = datetime.today().date() end_sell_date = datetime.today().date() return Product.add_or_update(vendor_id, remote_id, name, quota, total_quota, today_quota, total_amount, total_buy_amount, min_redeem_amount, max_redeem_amount, day_redeem_amount, interest_rate_hike, description, product_type, min_amount, max_amount, rate_type, rate, effect_day_condition, effect_day, effect_day_unit, redeem_type, start_sell_date, end_sell_date)
def sxb_asset(): """绑定账户. :reqheader Authorization: OAuth 2.0 Bearer Token :reqheader If-None-Match: 客户端缓存的 ETag :resheader ETag: 客户端可缓存的 ETag :status 200: 资产信息, :class:`.AssetResponseSchema` """ schema = AssetResponseSchema(strict=True) assets = Asset.gets_by_user_id(request.oauth.user.id_) vendor = Vendor.get_by_name(Provider.sxb) asset_response = dict(uid=-1, yesterday_profit=0, hold_amount=0, hold_profit=0, actual_annual_rate=0, rest_hold_amount=0, rest_redeem_amount=0, residual_redemption_times=0) for asset in assets: if asset.product.vendor.id_ == vendor.id_: asset_response['uid'] = asset.id_ asset_response['yesterday_profit'] += asset.yesterday_profit asset_response['hold_amount'] += asset.total_amount asset_response['hold_profit'] += asset.hold_profit asset_response['yesterday_profit'] += asset.yesterday_profit asset_response['rest_redeem_amount'] += asset.remaining_amount_today asset_response['residual_redemption_times'] += asset.residual_redemption_times if asset_response['rest_hold_amount'] == 0: asset_response[ 'rest_hold_amount'] = asset.product.total_buy_amount - asset.total_amount else: asset_response['rest_hold_amount'] -= asset.total_amount data, errors = schema.dump(asset_response) conditional_for_v2(json.dumps(data)) return jsonify(success=True, data=data, errors=errors)
def fillup_local(product_info, is_child_product=None): start_sell_date, end_sell_date = check_available_for_product(product_info) vendor_id = Vendor.get_by_name(Provider.sxb).id_ return Product.add_or_update(vendor_id, product_info.id_, product_info.name, product_info.quota, product_info.total_quota, product_info.today_quota, product_info.total_amount, product_info.total_buy_amount, product_info.min_redeem_amount, product_info.max_redeem_amount, product_info.day_redeem_amount, product_info.add_year_rate, product_info.remark, Product.Type.unlimited, product_info.min_amount, product_info.max_amount, product_info.return_rate_type.value, product_info.return_rate, product_info.effect_day_type.value, product_info.effect_day, product_info.effect_day_unit.value, product_info.is_redeem, start_sell_date, end_sell_date, is_child_product=is_child_product)
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 initialize_sxb(): g.sxb_account = None if hasattr(request, 'oauth'): vendor = Vendor.get_by_name(Provider.sxb) if vendor: g.sxb_account = NewAccount.get_by_local(vendor.id_, request.oauth.user.id_)
def mine(): """用户状况. :reqheader Authorization: OAuth 2.0 Bearer Token :status 200: 返回 :class:`~jupiter.views.api.v1.profile.ProfileSchema` """ profile_schema = ProfileSchema(strict=True) identity = Identity.get(request.oauth.user.id_) yixin_account = YixinAccount.get_by_local(request.oauth.user.id_) zw_account = ZhiwangAccount.get_by_local(request.oauth.user.id_) xm_account = XMAccount.get_by_local(request.oauth.user.id_) coupon_manager = CouponManager(request.oauth.user.id_) 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_) data = { 'user': request.oauth.user, 'has_mobile_phone': bool(request.oauth.user.mobile), 'has_identity': bool(identity), 'has_yixin_account': bool(yixin_account), 'has_zw_account': bool(zw_account), 'has_xm_account': bool(xm_account), 'has_sxb_account': bool(sxb_account), 'coupon_count': len(coupon_manager.available_coupons), 'is_old_user_of_yrd': False, 'masked_person_name': identity.masked_name if identity else '', 'red_packets': g.firewood_flow.balance } return jsonify(success=True, data=profile_schema.dump(data).data)
def update_to_hoarder_product(product): vendor_id = Vendor.get_by_name(Provider.xm).id_ Product.add_or_update( vendor_id, product.product_id, product.name, float(product.quota), float(product.total_amount), float(product.total_amount), float(product.total_amount), float(product.sold_amount), 0, 0, 0, 0, product.description, Product.Type.classic, product.min_amount, product.max_amount, # 固定收益率 1, product.annual_rate / 100, 1, 1, 1, Product.RedeemType.auto.value, product.start_sell_date, product.end_sell_date, product.expire_period, product.expire_period_unit)
def get_products(user=None): enabled_vendors = Vendor.get_enabled_vendors() matched_coupons = [] coupon_manager = None product_obj = { 'wallet': [], 'hoarder': [], 'help_url': url_for('activity.cake.index', _external=True) } if user: coupon_manager = CouponManager(user.id_) for vendor in enabled_vendors: products = [p for p in Product.get_products_by_vendor_id(vendor.id_)] for product in products: profile = COMMON_PRODUCT_PROFILE.get(vendor.provider) product.uid = product.id_ product.title = profile.get('title') product.activity_title = profile.get('activity_title') product.activity_introduction = profile.get( 'activity_introduction') product.annual_rate = product.rate * 100 product.tags = profile.get('tags') product.start_date = product.value_date rule_url = profile.get('withdraw_rule_url') product.withdraw_rule = url_for(rule_url, _external=True) if rule_url else '' if product.ptype is Product.Type.unlimited: product.annotations = {'has_coupons': False} product.period = profile.get('period') else: product.period = PERIODS.get(str(product.frozen_days)) if product.vendor.name == Provider.xm.value: product.uid = product.remote_id if coupon_manager: if product.vendor.name == Provider.xm.value: xm_product = XMFixedDuedayProduct.get( product.remote_id) matched_coupons = XMFixedDuedayProduct.get_product_annotations( coupon_manager, xm_product) product.annotations = {'has_coupons': len(matched_coupons) > 0} if product.is_sold_out: key = 'soldout' elif product.is_taken_down: key = 'offsale' elif product.is_pre_sale: key = 'presale' else: if product.ptype is Product.Type.unlimited: key = 'wallet_onsale' else: key = 'hoarder_onsale' product.display_status = PRODUCT_STATUS.get(key) if product.ptype is Product.Type.unlimited: product_obj['wallet'].append(product) else: product_obj['hoarder'].append(product) product_obj['wallet'].append(get_fund_product()) return product_obj
def purchase(): """选购规划产品, 创建理财单. :request: :class:`.products.xinmi.XinmiPurchaseSchema` or :class:`.products.sxb.PurchaseSchema` :reqheader Authorization: OAuth 2.0 Bearer Token :status 403: 因为未完成实名认证或产品方面原因, 购买请求被拒 :status 201: 订单已创建, 返回 :class:`.products.xinmi.XinmiOrderSchema` or :class:`.products.sxb.OrderSchema` """ result = request.get_json(force=True) if result['vendor'] == Provider.xm.value: if not g.xm_account: try: xm_auth(request.oauth.user.id_) g.xm_account = XMAccount.get_by_local(request.oauth.user.id_) except (XMAccountError, XMSignUpError) as e: abort(403, unicode(e)) try: order = xm_purchase(result, g) except (BankCardError, CouponOwnershipError, XMError) as e: abort(403, unicode(e)) except (XMProductError, XMTradeError) as e: abort(403, unicode(e)) except (CouponError, CouponUsageError) as e: abort(403, unicode(e)) except FirewoodException as e: abort(403, unicode(e)) return jsonify(success=True, data=order), 201 if result['vendor'] == Provider.sxb.value: if not g.sxb_account: try: sxb_auth(request.oauth.user.id_) vendor = Vendor.get_by_name(Provider.sxb) if vendor: g.sxb_account = HoardAccount.get_by_local( vendor.id_, request.oauth.user.id_) except SxbAccountError as e: abort(403, unicode(e)) try: order = sxb_purchase(result, g) except (BankCardError, CouponOwnershipError) as e: abort(403, unicode(e)) except SxbProductError as e: abort(403, unicode(e)) except SxbOrderError as e: abort(403, unicode(e)) except SxbTradeError as e: abort(403, unicode(e)) except (CouponError, CouponUsageError) as e: abort(403, unicode(e)) except FirewoodException as e: abort(403, unicode(e)) return jsonify(success=True, data=order), 201
def initialize_remote_account(): if hasattr(request, 'oauth'): g.xm_account = XMAccount.get_by_local(request.oauth.user.id_) vendor = Vendor.get_by_name(Provider.sxb) if vendor: g.sxb_account = HoardAccount.get_by_local(vendor.id_, request.oauth.user.id_) else: g.xm_account = None g.sxb_account = None
def sxb_withdraw(): vendor = Vendor.get_by_name(Provider.sxb) products = Product.get_products_by_vendor_id(vendor_id=vendor.id_) # 对随心宝产品默认取第一款上线产品为数据来源(只会上线一款随心宝产品) for p in products: if p.is_on_sale: break if not p: abort(403, u'产品已下线,请稍后再试') max_free_redeem_times = 5 total_buy_amount = p.total_buy_amount min_redeem_amount = p.min_redeem_amount day_redeem_amount = p.day_redeem_amount return render_template('wallet/sxb_withdraw_rule.html', **locals())
def index(): if g.user and HoardProfile.get(g.user.id_): return redirect(url_for('savings.mine.index')) amount = get_savings_amount() user_count = get_user_count() xm_products = XMFixedDuedayProduct.get_all() vendor = Vendor.get_by_name(Provider.sxb) sxb_products = Product.get_products_by_vendor_id(vendor.id_) return render_template('savings/index.html', amount=amount, user_count=user_count, xm_products=xm_products, sxb_products=sxb_products, cur_path='savings')
def bankcards(): """用户已绑的银行卡列表. :query partner: 可选参数, 按合作方支持情况限制返回结果. 目前可为: - ``"zw"`` 指旺 (攒钱助手) - ``"xm"`` 新米 (攒钱助手) - ``"sxb"`` 随心宝 (攒钱助手) - ``"zs"`` 中山证券 (零钱包) :reqheader Authorization: OAuth 2.0 Bearer Token :reqheader If-None-Match: 客户端缓存的 ETag :resheader ETag: 客户端可缓存的 ETag :status 304: 客户端缓存未过期, 无需返回数据 :status 200: 返回 :class:`.BankCardSchema` 列表 """ bankcard_schema = BankCardSchema(strict=True, many=True) partner = request.args.get('partner', type=Partner) bankcard_list = g.bankcard_manager.get_all() if partner is not None: bankcard_list = [ bankcard for bankcard in bankcard_list if partner in bankcard.bank.available_in ] if partner is Partner.zs: bankcard_list = [ bankcard for bankcard in bankcard_list if is_bound_bankcard(bankcard, zhongshan) ] inject_bankcard_amount_limit(partner, bankcard_list) if partner: if partner is Partner.sxb: vendor = Vendor.get_by_name(Provider.sxb) for bankcard in bankcard_list: if is_bound_sxb_bankcard(bankcard, vendor): bankcard.is_default = True else: bankcard.is_default = False bankcard_data = bankcard_schema.dump(bankcard_list).data conditional_for('{0}#{1}#{2}#{3}'.format( item['uid'], item['amount_limit'], item['is_bound_in_wallet'], item['is_default']) for item in bankcard_data) return jsonify(success=True, data=bankcard_data)
def test_add_or_update(self): self.init_product() vendor_id = Vendor.get_by_name(Provider.sxb).id_ remote_id = '2015122217504424733' name = '随心宝测试产品01' quota = 1000.0 total_quota = 200000.0 today_quota = 10000.0 total_amount = 3000000.0 total_buy_amount = 10000.0 min_redeem_amount = 1000.0 max_redeem_amount = 10000.0 day_redeem_amount = 1000.0 interest_rate_hike = 0.001 description = 'Test...' product_type = Product.Type.unlimited min_amount = 100 max_amount = 10000 rate_type = 3 rate = 0.083 effect_day_condition = 'C' effect_day = 1 effect_day_unit = '3' redeem_type = Product.RedeemType.user.value start_sell_date = datetime.today().date() end_sell_date = datetime.today().date() products = Product.get_products_by_vendor_id(vendor_id) assert len(products) > 0 assert products[0].vendor_id == int(vendor_id) assert products[0].quota == quota quota = Decimal('4000.0') updated_product = Product.add_or_update(vendor_id, remote_id, name, quota, total_quota, today_quota, total_amount, total_buy_amount, min_redeem_amount, max_redeem_amount, day_redeem_amount, interest_rate_hike, description, product_type, min_amount, max_amount, rate_type, rate, effect_day_condition, effect_day, effect_day_unit, redeem_type, start_sell_date, end_sell_date) assert updated_product.id_ == products[0].id_ assert updated_product.vendor_id == int(vendor_id) assert updated_product.quota == quota
def get_fund_product(): """基金产品""" dashboard = PublicDashboard.today() profile = COMMON_PRODUCT_PROFILE.get(Provider.ms) product = dict(name=zhongshan.fund_name, title=profile.get('title'), vendor=Vendor.get_by_name(Provider.ms), activity_title=profile.get('activity_title'), activity_introduction=profile.get('activity_introduction'), annual_rate=dashboard.latest_annual_rate.annual_rate, tags=profile.get('tags'), display_status=PRODUCT_STATUS.get('wallet_onsale'), company=zhongshan.fund_company_name, period=profile.get('period'), code=zhongshan.fund_code, bank_name=zhongshan.fund_bank_name) return product
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 test_savings_products_all(client, oauth_token, oauth_client, xm_product): headers = { 'X-Client-ID': oauth_client.client_id, 'X-Client-Secret': oauth_client.client_secret } r = client.get(get_testurl_v2(testing_urls['all']), headers=headers) assert r.status_code == 200 assert r.data['success'] is True assert r.data['data']['wallet'] != [] wallet = r.data['data']['wallet'] vendor = Vendor.get_by_name(Provider.sxb) sxb_products = SXBProduct.get_products_by_vendor_id(vendor.id_) for i in range(len(sxb_products)): product_schema_assert(wallet[i], str(sxb_products[i].id_)) fund = wallet[2] assert 'name' in fund assert 'title' in fund assert 'activity_title' in fund assert 'activity_introduction' in fund assert 'annual_rate' in fund assert 'tags' in fund assert 'display_status' in fund
def test_savings_recommend_product_with_old_user( mock_get_order_amount_by_user, mock_get_total_orders, mock_has_bought_newcomer_product, client, oauth_client, oauth_token): headers = { 'X-Client-ID': oauth_client.client_id, 'X-Client-Secret': oauth_client.client_secret } # 购买新手标 # 登录,访问路由,查找推荐产品 client.load_token(oauth_token) mock_get_order_amount_by_user.return_value = 1 mock_get_total_orders.return_value = 1 mock_has_bought_newcomer_product.return_value = True # 访问路由,查找推荐产品 r = client.get(get_testurl_v2(testing_urls['recommend']), headers=headers) # 对比推荐产品,必须为随心攒 assert r.status_code == 200 assert r.data['success'] is True assert r.data['data']['wallet'] != [] wallet = r.data['data']['wallet'][0] vendor = Vendor.get_by_name(Provider.sxb) sxb_products = SXBProduct.get_products_by_vendor_id(vendor.id_) assert 'withdraw_rule' in wallet product_schema_assert(wallet, str(sxb_products[1].id_))
# coding: utf-8 from libs.utils.log import bcolors from core.models.hoarder.vendor import Vendor, Provider if __name__ == '__main__': bcolors.run('Add product_vendor.') Vendor.add(Provider.sxb.value, 'sxb') Vendor.add(Provider.xm.value, 'xm') Vendor.add(Provider.zw.value, 'zw') Vendor.add(Provider.ms.value, 'ms') bcolors.success('Init product vendor done.')
def async_sxb_asset(): vendor = Vendor.get_by_name(Provider.sxb) product_ids = Product.get_product_ids_by_vendor_id(vendor_id=vendor.id_) for product_id in product_ids: for id_ in Asset.get_ids_by_product_id(product_id): hoarder_async_asset.produce(str(id_))
def init_vendor(self): return Vendor.add(Provider.sxb.value, 'test')
def sxb_user(sqlstore, redis, user): vendor = Vendor.get_by_name(Provider.sxb) sxbuser = SXBAccount.get_by_local(vendor.id_, user.id_) if not sxbuser: return SXBAccount.bind(vendor.id_, user.id_, u'1234abcd') return sxbuser
def get_sxb_products(user_id): vendor = Vendor.get_by_name(Provider.sxb) vendor_product_profile = PRODUCT_PROFILE[vendor.provider] products = [ p for p in Product.get_products_by_vendor_id(vendor.id_) if p.kind is Product.Kind.father ] new_products = [ p for p in NewComerProduct.get_products_by_vendor_id(vendor.id_) if p.kind is Product.Kind.child ] products.extend(new_products) for product in products: if product.kind is Product.Kind.child: father_product = NewComerProduct.get_father_product_by_vendor_id( product.vendor.id_) product_id = father_product.id_ else: product_id = product.id_ assets = Asset.gets_by_user_id_with_product_id(user_id, product_id) product.rest_hold_amount = round_half_up(product.max_amount, 2) if assets: rest_hold_amount = product.max_amount - sum(asset.total_amount for asset in assets) product.rest_hold_amount = rest_hold_amount if rest_hold_amount > 0 else 0 product.remaining_amount_today = sum( [asset.remaining_amount_today for asset in assets]) if product.is_on_sale: product.button_display_text, product.button_click_text = ( sale_display_text['on_sale']) elif product.is_taken_down: product.button_display_text, product.button_click_text = ( sale_display_text['late_morning_off_sale'] if product.kind is Product.Kind.father else sale_display_text['middle_morning_off_sale']) elif product.is_sold_out: product.button_display_text, product.button_click_text = ( sale_display_text['late_morning_sold_out'] if product.kind is Product.Kind.father else sale_display_text['late_morning_sold_out']) if product.kind is Product.Kind.child: product.rest_hold_amount = 10000 product.max_amount = 10000 product.introduction = vendor_product_profile['new_comer'][ 'product_introduction'] product.title = vendor_product_profile['new_comer'][ 'product_title'] product.activity_title = vendor_product_profile['new_comer'][ 'activity_title'] product.activity_introduction = ( vendor_product_profile['new_comer']['activity_introduction']) product.annual_rate = product.operation_num * 100 else: product.introduction = vendor_product_profile['sxb'][ 'product_introduction'] product.title = vendor_product_profile['sxb']['product_title'] product.activity_title = vendor_product_profile['sxb'][ 'activity_title'] product.activity_introduction = vendor_product_profile['sxb'][ 'activity_introduction'] product.annual_rate = product.rate * 100 # is_either_sold_out, unique_product_id 为兼容老产品字段 product.is_either_sold_out = product.is_sold_out product.unique_product_id = product.remote_id product.is_able_purchased = product.is_on_sale product.check_benifit_date = product.value_date + timedelta(days=1) product.withdraw_rule = url_for('hybrid.rules.sxb_withdraw', _external=True) product.agreement = url_for('savings.landing.agreement_xinmi', _external=True) product._total_amount = 0 product.annotations = [] return products