Exemple #1
0
 def test_add_order_failed_by_strategy(self):
     self.white_list.remove(self.user.id_)
     with raises(InvalidProductError):
         PlaceboOrder.add(user_id=self.user.id_,
                          product_id=self.product.id_,
                          bankcard_id=self.bankcard.id_,
                          amount=decimal.Decimal('100'))
Exemple #2
0
 def test_add_order_failed_by_identity(self):
     self.identity.remove(self.user.id_)
     with raises(InvalidIdentityError):
         PlaceboOrder.add(user_id=self.user.id_,
                          product_id=self.product.id_,
                          bankcard_id=self.bankcard.id_,
                          amount=decimal.Decimal('100'))
Exemple #3
0
 def test_add_order_failed_by_amount_overflow(self):
     invalid_amount_list = [
         decimal.Decimal('-1'),
         decimal.Decimal('NaN'),
         decimal.Decimal('101'),
     ]
     for invalid_amount in invalid_amount_list:
         with raises(OutOfRangeError):
             PlaceboOrder.add(user_id=self.user.id_,
                              product_id=self.product.id_,
                              bankcard_id=self.bankcard.id_,
                              amount=invalid_amount)
Exemple #4
0
 def test_add_order_failed_by_outdated_product(self):
     outdated_product = PlaceboProduct.add(
         strategy=self.check_white_list,
         min_amount=decimal.Decimal('100.00'),
         max_amount=decimal.Decimal('100.00'),
         start_sell_date=datetime.date.today() - datetime.timedelta(days=2),
         end_sell_date=datetime.date.today() - datetime.timedelta(days=1),
         frozen_days=10,
         annual_rate=decimal.Decimal('12.2'))
     with raises(OffShelfError):
         PlaceboOrder.add(user_id=self.user.id_,
                          product_id=outdated_product.id_,
                          bankcard_id=self.bankcard.id_,
                          amount=decimal.Decimal('100'))
Exemple #5
0
    def test_assign_hike(self):
        order = PlaceboOrder.add(user_id=self.user.id_,
                                 product_id=self.product.id_,
                                 bankcard_id=self.bankcard.id_,
                                 amount=None)
        assert order.profit_annual_rate == decimal.Decimal('12.2')
        assert order.annual_rate_hike == decimal.Decimal('0')

        order.assign_annual_rate_hike(decimal.Decimal('0.11'))
        assert order.profit_annual_rate == decimal.Decimal('12.31')
        assert order.annual_rate_hike == decimal.Decimal('0.11')

        order = PlaceboOrder.get(order.id_)
        assert order.profit_annual_rate == decimal.Decimal('12.31')
        assert order.annual_rate_hike == decimal.Decimal('0.11')
Exemple #6
0
def yxpay_placebo_notify():
    if request.remote_addr not in ['111.207.203.195', '219.143.6.195']:
        abort(403)

    try:
        response = make_response(json.loads(request.form['msg']),
                                 SinglePaymentResult)
        status = YixinPaymentStatus(int(response.state))
    except (ValueError, TypeError):
        abort(400)

    order = PlaceboOrder.get_by_biz_id(response.biz_id)
    if not order:
        abort(404)

    if status is YixinPaymentStatus.SUCCESS:
        order.mark_as_exited(response)
    else:
        sentry.captureMessage('体验金订单回款失败',
                              extra={
                                  'order_id': order.id_,
                                  'biz_id': response.biz_id,
                                  'status': status,
                              })

    return '', 204
Exemple #7
0
    def test_add_order_success(self):
        order = PlaceboOrder.add(user_id=self.user.id_,
                                 product_id=self.product.id_,
                                 bankcard_id=self.bankcard.id_,
                                 amount=decimal.Decimal('100'))
        order_with_default_amount = PlaceboOrder.add(
            user_id=self.user.id_,
            product_id=self.product.id_,
            bankcard_id=self.bankcard.id_,
            amount=None)

        assert order.amount == order_with_default_amount.amount
        assert order.status is PlaceboOrder.Status.running
        assert order.product == self.product
        assert order.bankcard == self.bankcard
        assert order.profit_period.value == 10
        assert order.profit_period.unit == 'day'
        assert order.profit_annual_rate == decimal.Decimal('12.2')
        assert order.owner == self.user

        assert order.biz_id.startswith('gh:s:p:')
        assert PlaceboOrder.get_by_biz_id(order.biz_id) == order

        all_ids = [order_with_default_amount.id_, order.id_]
        all_orders = [order_with_default_amount, order]
        assert PlaceboOrder.get_multi(all_ids) == all_orders
        assert PlaceboOrder.get_multi(all_ids[1:]) == all_orders[1:]
        assert PlaceboOrder.get_multi(all_ids[:-1]) == all_orders[:-1]

        assert PlaceboOrder.get_ids_by_user(self.user.id_) == all_ids
Exemple #8
0
 def test_calculation(self):
     order = PlaceboOrder.add(user_id=self.user.id_,
                              product_id=self.product.id_,
                              bankcard_id=self.bankcard.id_,
                              amount=None)
     order.creation_time = datetime.datetime(2009, 10, 11, 12, 13, 14)
     assert order.start_date == datetime.date(2009, 10, 11)
     assert order.due_date.date() == datetime.date(2009, 10, 21)
     assert unicode(round_half_up(order.calculate_profit_amount(),
                                  2)) == '0.33'
Exemple #9
0
    def test_assign_hike_failure(self):
        order = PlaceboOrder.add(user_id=self.user.id_,
                                 product_id=self.product.id_,
                                 bankcard_id=self.bankcard.id_,
                                 amount=None)

        with raises(ValueError):
            order.assign_annual_rate_hike(decimal.Decimal('-0.11'))

        order.transfer_status(PlaceboOrder.Status.exiting)
        with raises(NotRunningError):
            order.assign_annual_rate_hike(decimal.Decimal('0.11'))
Exemple #10
0
    def test_get_multi(self):
        orders = [
            PlaceboOrder.add(user_id=self.user.id_,
                             product_id=self.product.id_,
                             bankcard_id=self.bankcard.id_,
                             amount=None) for _ in xrange(5)
        ]
        ids = [o.id_ for o in orders]
        assert PlaceboOrder.get_multi(ids) == orders
        assert list(PlaceboOrder.iter_multi_for_exiting()) == []

        with freeze_time(orders[0].creation_time +
                         datetime.timedelta(days=10)):
            exiting_orders = list(PlaceboOrder.iter_multi_for_exiting())
            assert exiting_orders == [(order, order.product)
                                      for order in reversed(orders)]

            for order, _ in exiting_orders:
                order.transfer_status(PlaceboOrder.Status.exiting)
            exiting_orders = list(PlaceboOrder.iter_multi_for_exiting())
            assert exiting_orders == []
Exemple #11
0
 def test_status(self):
     order = PlaceboOrder.add(user_id=self.user.id_,
                              product_id=self.product.id_,
                              bankcard_id=self.bankcard.id_,
                              amount=None)
     assert order.status is PlaceboOrder.Status.running
     assert order.transfer_status(
         PlaceboOrder.Status.exiting) is PlaceboOrder.Status.exiting
     assert order.status is PlaceboOrder.Status.exiting
     assert order.transfer_status(
         PlaceboOrder.Status.exited) is PlaceboOrder.Status.exited
     assert order.status is PlaceboOrder.Status.exited
Exemple #12
0
def placebo_order_exiting(order_id):
    from core.models.hoard.placebo import PlaceboOrder

    order = PlaceboOrder.get(order_id)

    if order.status is PlaceboOrder.Status.running:
        order.transfer_status(PlaceboOrder.Status.exiting)
        response = pay_for_order(order)
        order.mark_as_exited(response)

    if order.status is PlaceboOrder.Status.exiting:
        response = track_for_order(order)
        order.mark_as_exited(response)
Exemple #13
0
def obtain_spring_gift(user, order):
    """领取体验金."""
    gift = SpringGift.get_by_user(user)
    if not (gift and user.is_normal_account()
            and order.status is ZhiwangOrder.Status.success):
        return

    product = get_placebo_product()
    try:
        order = PlaceboOrder.add(user_id=user.id_,
                                 product_id=product.id_,
                                 bankcard_id=order.bankcard.id_,
                                 amount=SpringGift.placebo_order_amount)
    except InvalidProductError:
        return

    is_affected = gift.mark_as_obtained(user.id_, order.id_)
    if is_affected:
        notify_spring_gift(user, gift)
    else:
        order.transfer_status(PlaceboOrder.Status.failure)
Exemple #14
0
    def test_add_order_failed_by_invalid_id(self):
        with raises(ValueError) as error:
            PlaceboOrder.add(user_id=self.user.id_ + '10',
                             product_id=self.product.id_,
                             bankcard_id=self.bankcard.id_,
                             amount=decimal.Decimal('100'))
        assert error.value.args[0] == 'invalid user_id'

        with raises(ValueError) as error:
            PlaceboOrder.add(user_id=self.user.id_,
                             product_id=self.product.id_ + '10',
                             bankcard_id=self.bankcard.id_,
                             amount=decimal.Decimal('100'))
        assert error.value.args[0] == 'invalid product_id'

        with raises(ValueError) as error:
            PlaceboOrder.add(user_id=self.user.id_,
                             product_id=self.product.id_,
                             bankcard_id=self.bankcard.id_ + '10',
                             amount=decimal.Decimal('100'))
        assert error.value.args[0] == 'invalid bankcard_id'
Exemple #15
0
def get_placebo_order(user_id):
    """获取本次活动体验金订单."""
    order_ids = PlaceboOrder.get_ids_by_user(user_id)
    orders = (PlaceboOrder.get(order_id) for order_id in order_ids)
    product = get_placebo_product()
    return first((o for o in orders if o.product == product), None)
Exemple #16
0
def main():
    for order, product in PlaceboOrder.iter_multi_for_exiting():
        placebo_order_exiting.produce(order.id_)
Exemple #17
0
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)