예제 #1
0
파일: php_utils.py 프로젝트: 859162000/wlba
def php_commission(user, product_id, start):
    """
    月利宝的表存的是php那边的流水.直接从这获取
    :param user:
    :param product_id:
    :param start:
    :return:
    """
    _amount = MonthProduct.objects.filter(user=user,
                                          product_id=product_id,
                                          created_at__gt=start,
                                          cancel_status=False).aggregate(
                                              Sum('amount'))
    if _amount['amount__sum']:
        commission = decimal.Decimal(
            _amount['amount__sum']) * decimal.Decimal("0.003")
        commission = commission.quantize(decimal.Decimal('0.01'),
                                         rounding=decimal.ROUND_HALF_DOWN)
        first_intro = IntroducedBy.objects.filter(user=user).first()
        if first_intro and first_intro.introduced_by:
            first = MarginKeeper(first_intro.introduced_by)
            first.deposit(commission, description=u'月利宝一级淘金', catalog=u"全民淘金")

            income = PhpIncome(user=first_intro.introduced_by,
                               invite=user,
                               level=1,
                               product_id=product_id,
                               amount=_amount['amount__sum'],
                               earning=commission,
                               order_id=first.order_id,
                               paid=True,
                               created_at=timezone.now())
            income.save()
예제 #2
0
    def test_purchase(self):
        user1_margin_keeper = MarginKeeper(self.user1)
        user1_margin_keeper.deposit(100000)

        product = MockGenerator.generate_staging_p2p(u'test',
                                                     100000,
                                                     per_user=0.1)
        user1_trader = P2PTrader(product, self.user1)

        # user1_trader.purchase(2000)

        user1_trader.purchase(1000)

        margin_records = MarginRecord.objects.all()
        self.assertEqual(len(margin_records), 2)

        for margin_record in margin_records:
            self.assertIsNotNone(margin_record.order_id)

        order = Order.objects.get(pk=user1_trader.order_id)
        notes = order.notes.all()

        self.assertEqual(len(notes), 2)

        self.assertEqual(notes[0].extra_data['status'], u'份额确认')
예제 #3
0
def commission(user, product, equity, start):
    """
    计算全民佣金,千三,取消第二级
    :param user:
    :param product:
    :param equity:
    :param start:
    """
    _amount = P2PRecord.objects.filter(user=user,
                                       product=product,
                                       create_time__gt=start).aggregate(
                                           Sum('amount'))
    if _amount['amount__sum'] and _amount['amount__sum'] <= equity:
        commission = decimal.Decimal(
            _amount['amount__sum']) * decimal.Decimal("0.003")
        commission = commission.quantize(decimal.Decimal('0.01'),
                                         rounding=decimal.ROUND_HALF_DOWN)
        first_intro = IntroducedBy.objects.filter(user=user).first()
        if first_intro and first_intro.introduced_by:
            first = MarginKeeper(first_intro.introduced_by)
            first.deposit(commission, catalog=u"全民淘金")

            income = Income(user=first_intro.introduced_by,
                            invite=user,
                            level=1,
                            product=product,
                            amount=_amount['amount__sum'],
                            earning=commission,
                            order_id=first.order_id,
                            paid=True,
                            created_at=timezone.now())
            income.save()
예제 #4
0
    def test_settle(self):
        user1_margin_keeper = MarginKeeper(self.user1)
        user1_margin_keeper.deposit(100000)

        product = MockGenerator.generate_staging_p2p(u'test',
                                                     100000,
                                                     per_user=1)
        user1_trader = P2PTrader(product, self.user1)
        user1_trader.purchase(100000)

        product = P2PProduct.objects.get(pk=product.id)

        # Now The product status should be pre settle, which means some one should do the final check,
        # Do money transfer, and if everything works, then he or she should change status to 还款中
        product = P2PProduct.objects.get(pk=product.id)
        self.assertEqual(product.status, u'满标待打款')

        product.status = u'满标已打款'
        product.save()

        operator = P2POperator()
        operator.preprocess_for_settle(product=product)

        product = P2PProduct.objects.get(pk=product.id)
        self.assertEqual(product.status, u'满标待审核')

        # Now the equity should has contract, user should has amortization plan
        equity = P2PEquity.objects.filter(user=self.user1,
                                          product=product).first()

        try:
            f = equity.contract.open('r')
        except ValueError, e:
            self.fail("The contract not generated as expected")
예제 #5
0
파일: trade.py 프로젝트: 859162000/wlba
    def __init__(self, product, user, order_id=None, request=None):
        self.user = user
        self.product = product

        if self.product.status != u"正在招标":
            raise P2PException(u'购买的标不在招标状态')

        self.request = request
        if order_id is None:
            self.order_id = OrderHelper.place_order(user,
                                                    order_type=u'产品申购',
                                                    product_id=product.id,
                                                    status=u'新建').id
        else:
            self.order_id = order_id
        self.margin_keeper = MarginKeeper(user=user, order_id=self.order_id)
        self.product_keeper = ProductKeeper(product, order_id=self.order_id)
        self.equity_keeper = EquityKeeper(user=user,
                                          product=product,
                                          order_id=self.order_id)
        if request:
            self.device = split_ua(request)
            self.device_type = self.device['device_type']
        else:
            self.device = split_ua(request)
            self.device_type = "pc"
예제 #6
0
    def test_full_process(self):
        user1_margin_keeper = MarginKeeper(self.user1)
        user1_margin_keeper.deposit(100000)
        operator = P2POperator()

        product = MockGenerator.generate_staging_p2p(u'测试用P2P产品第一号',
                                                     100000,
                                                     per_user=1)

        # Run the operator and check nothing happened

        P2PTrader(product, self.user1).purchase(100000)

        product = P2PProduct.objects.first()
        self.assertEqual(product.status, u'满标待打款')

        # Stimulate that the money already paid
        product.status = u'满标已打款'
        product.save()

        # status -> 满标待审核
        operator.watchdog()
        product = P2PProduct.objects.first()
        user_amortizations = UserAmortization.objects.filter(
            product_amortization__in=product.amortizations.all())

        user_amortizations_count = len(user_amortizations)

        # Some body may manually set status to 满标已打款 in case some error detected, system should
        # support this case
        product = P2PProduct.objects.get(pk=product.id)
        product.status = u'满标已打款'

        # Regenerate user amortization plan
        operator.watchdog()

        product = P2PProduct.objects.first()
        user_amortizations = UserAmortization.objects.filter(
            product_amortization__in=product.amortizations.all())

        # Even we regenerate everything, the user_amortization account should be the same
        self.assertEqual(len(user_amortizations), user_amortizations_count)

        # 满标待审核 -> 满标已审核
        product = P2PProduct.objects.first()
        ProductKeeper(product).audit(self.user1)

        # status -> 还款中
        operator.watchdog()
        product = P2PProduct.objects.get(pk=product.id)
        self.assertEqual(product.status, u'还款中')

        for a in product.amortizations.all():
            a.ready_for_settle = True
            a.save()
            operator.watchdog()

        product = P2PProduct.objects.get(pk=product.id)
        self.assertEqual(product.status, u'已完成')
예제 #7
0
파일: maintain.py 프로젝트: 859162000/wlba
def reward_user_5(user, introduced_by, reward_type, got_amount, product,
                  only_show):
    reward = Reward.objects.filter(is_used=False, type=reward_type).first()

    text_content = u"【网利宝】您在邀请好友送收益的活动中,获得%s元收益,收益已经发放至您的网利宝账户。请注意查收。回复TD退订4008-588-066【网利宝】" % got_amount
    if only_show is not True:
        send_messages.apply_async(
            kwargs={
                "phones": [user.wanglibaouserprofile.phone],
                "messages": [text_content]
            })
    if only_show is not True:
        earning = Earning()
        earning.amount = got_amount
        earning.type = 'I'
        earning.product = product
        order = OrderHelper.place_order(introduced_by,
                                        Order.ACTIVITY,
                                        u"邀请送收益活动赠送",
                                        earning=model_to_dict(earning))
        earning.order = order
        keeper = MarginKeeper(introduced_by, order.pk)

        # 赠送活动描述
        desc = u'%s,邀请好友首次理财活动中,活赠%s元' % (
            introduced_by.wanglibaouserprofile.name, got_amount)
        earning.margin_record = keeper.deposit(got_amount, description=desc)
        earning.user = introduced_by
        earning.save()

    message_content = u"您在邀请好友送收益的活动中,您的好友%s在活动期间完成首次投资,根据活动规则,您获得%s元收益。<br/>\
                      <a href = 'https://www.wanglibao.com/accounts/home/'>查看账户余额</a><br/>\
                      感谢您对我们的支持与关注。<br/>\
                      网利宝" % (safe_phone_str(
        user.wanglibaouserprofile.phone), got_amount)

    if only_show is not True:
        RewardRecord.objects.create(user=introduced_by,
                                    reward=reward,
                                    description=message_content)
        inside_message.send_one.apply_async(
            kwargs={
                "user_id": introduced_by.id,
                "title": u"邀请送收益活动",
                "content": message_content,
                "mtype": "activity"
            })
    else:
        print message_content
        print introduced_by.wanglibaouserprofile.name
        print safe_phone_str(user.wanglibaouserprofile.phone)
        print text_content
예제 #8
0
    def handle_margin(self, amount, order_id, user_id, ip, response_content, device):
        try:
            pay_info = PayInfo.objects.select_for_update().filter(order_id=order_id).first()
        except Exception:
            logger.error("orderId:%s, order not exist, handle margin, try error" % order_id)
            return {"ret_code": 20085, "message": "order not exist, handle margin, try error"}

        if not pay_info:
            return {"ret_code": 20131, "message": "order not exist"}
        if pay_info.status == PayInfo.SUCCESS:
            return {"ret_code": 0, "message": PayResult.DEPOSIT_SUCCESS, "amount": amount}

        pay_info.error_message = ""
        pay_info.response = response_content
        pay_info.response_ip = ip

        if pay_info.amount != amount:
            pay_info.status = PayInfo.FAIL
            pay_info.error_message += u' 金额不匹配'
            logger.error("orderId:%s amount:%s, response amount:%s" % (order_id, pay_info.amount, amount))
            rs = {"ret_code": 20132, "message": PayResult.EXCEPTION}
        elif pay_info.user_id != user_id:
            pay_info.status = PayInfo.FAIL
            pay_info.error_message += u"用户不匹配"
            logger.error("orderId:%s 充值用户ID不匹配" % order_id)
            rs = {"ret_code": 20133, "message": PayResult.EXCEPTION}
        else:
            pay_info.fee = self.FEE
            keeper = MarginKeeper(pay_info.user, pay_info.order.pk)
            margin_record = keeper.deposit(amount)
            pay_info.margin_record = margin_record
            pay_info.status = PayInfo.SUCCESS
            logger.error("orderId:%s success" % order_id)
            rs = {"ret_code": 0, "message": "success", "amount": amount, "margin": margin_record.margin_current}

        pay_info.save()
        if rs['ret_code'] == 0:
            try:
                # fix@chenweibi, add order_id, handle_margin已经废弃未被使用
                tools.deposit_ok.apply_async(kwargs={"user_id": pay_info.user.id, "amount": pay_info.amount,
                                                     "device": device, "order_id": order_id})
            except:
                pass

            # 充值成功后,更新本次银行使用的时间
            if len(pay_info.card_no) == 10:
                Card.objects.filter(user=pay_info.user, no__startswith=pay_info.card_no[:6], no__endswith=pay_info.card_no[-4:]).update(last_update=timezone.now())
            else:
                Card.objects.filter(user=pay_info.user, no=pay_info.card_no).update(last_update=timezone.now())

        OrderHelper.update_order(pay_info.order, pay_info.user, pay_info=model_to_dict(pay_info), status=pay_info.status)
        return rs
예제 #9
0
    def generate(cls, clean=False):
        User = get_user_model()

        users = User.objects.all()

        for u in users:
            if not hasattr(u, 'margin'):
                margin = Margin(user=u)
                margin.save()

        for u in users:
            order = OrderHelper.place_order()
            keeper = MarginKeeper(order_id=order.id, user=u)
            keeper.deposit(100000000)
예제 #10
0
파일: views.py 프로젝트: 859162000/wlba
    def post(self, request):
        uuid = request.POST.get('uuid', '')
        error_message = request.POST.get('error_message', '')
        #try:
        #    payinfo = PayInfo.objects.get(uuid=uuid, type='W')
        #except PayInfo.DoesNotExist:
        #    return HttpResponse({
        #        u"没有找到 %s 该记录" % uuid
        #    })

        payinfo = PayInfo.objects.filter(uuid=uuid, type='W').first()
        if not payinfo:
            return HttpResponse({u"没有找到 %s 该记录" % uuid})

        if payinfo.status == PayInfo.FAIL or payinfo.status == PayInfo.SUCCESS:
            logger.info(
                "The withdraw status [%s] already process , ignore it" % uuid)
            return HttpResponse({u"该%s 请求已经处理过,请勿重复处理" % uuid})

        marginKeeper = MarginKeeper(payinfo.user)
        # 提现审核失败回滚时需要将扣除的各手续费返还
        total_amount = payinfo.amount + payinfo.fee + payinfo.management_fee
        marginKeeper.withdraw_rollback(total_amount,
                                       error_message,
                                       uninvested=payinfo.management_amount)
        payinfo.status = PayInfo.FAIL
        payinfo.error_message = error_message
        payinfo.confirm_time = None
        payinfo.save()

        # 短信通知添加用户名
        name = payinfo.user.wanglibaouserprofile.name or u'用户'

        send_messages.apply_async(
            kwargs={
                "phones": [payinfo.user.wanglibaouserprofile.phone],
                "messages": [messages.withdraw_failed(name, error_message)]
            })

        title, content = messages.msg_withdraw_fail(timezone.now(),
                                                    payinfo.amount)
        inside_message.send_one.apply_async(
            kwargs={
                "user_id": payinfo.user.id,
                "title": title,
                "content": content,
                "mtype": "withdraw"
            })

        return HttpResponse({u"该 %s 请求已经处理完毕" % uuid})
예제 #11
0
 def settle(self, savepoint=True):
     with transaction.atomic(savepoint=savepoint):
         equity_query = P2PEquity.objects.filter(user=self.user,
                                                 product=self.product)
         if (not equity_query.exists()) or (len(equity_query) != 1):
             raise P2PException('can not get equity info.')
         equity = equity_query.first()
         equity.confirm = True
         equity.confirm_at = timezone.now()
         equity.save()
         catalog = u'申购确认'
         description = u'用户份额确认(%d)' % equity.equity
         self.__tracer(catalog, equity.equity, description)
         user_margin_keeper = MarginKeeper(self.user)
         user_margin_keeper.settle(equity.equity, savepoint=False)
예제 #12
0
    def handle_withdraw_result(cls, data):
        order_id = data.get('OrdId', '')
        try:
            pay_info = PayInfo.objects.select_for_update().get(pk=order_id)
        except PayInfo.DoesNotExist:
            logger.warning('Order not found, order id: ' + order_id + ', response: ' + str(data))
            return PayResult.EXCEPTION

        if pay_info.status == PayInfo.FAIL:
            return PayResult.WITHDRAW_FAIL

        pay_info = PayInfo.objects.select_for_update().get(pk=order_id)
        pay_info.response = str(data)
        pay_info.error_code = data.get('RespCode', '')
        pay_info.error_message = data.get('RespDesc', '')
        transaction_status = data.get('TransStat', '')

        keeper = MarginKeeper(pay_info.user, pay_info.order.pk)

        try:
            pay = HuifuPay()
            if pay.verify_sign(data, HuifuPay.WITHDRAW_FIELDS):
                if data['RespCode'] == '000':
                    if transaction_status == 'S':
                        if pay_info.status != PayInfo.SUCCESS:
                            keeper.withdraw_ack(pay_info.total_amount)
                        pay_info.status = PayInfo.SUCCESS
                        result = PayResult.WITHDRAW_SUCCESS
                    elif transaction_status == 'I':
                        pay_info.status = PayInfo.ACCEPTED
                        result = PayResult.WITHDRAW_SUCCESS
                    elif transaction_status == 'F':
                        is_already_successful = False
                        if pay_info.status == 'S':
                            is_already_successful = True
                        pay_info.status = PayInfo.FAIL
                        result = PayResult.WITHDRAW_FAIL
                        keeper.withdraw_rollback(pay_info.total_amount, u'', is_already_successful)
                else:
                    pay_info.status = PayInfo.FAIL
                    result = PayResult.WITHDRAW_FAIL
                    keeper.withdraw_rollback(pay_info.total_amount)
            else:
                pay_info.status = PayInfo.EXCEPTION
                result = PayResult.EXCEPTION
                pay_info.error_message = 'Invalid signature'
                logger.fatal('invalid signature. order id: %s', str(pay_info.pk))
        except(socket.error, SignException) as e:
            result = PayResult.EXCEPTION
            pay_info.status = PayInfo.EXCEPTION
            pay_info.error_message = str(e)
            logger.fatal('unexpected error. order id: %s. exception: %s', str(pay_info.pk), str(e))

        pay_info.save()
        OrderHelper.update_order(pay_info.order, pay_info.user, pay_info=model_to_dict(pay_info), status=pay_info.status)
        return result
예제 #13
0
파일: trade.py 프로젝트: 859162000/wlba
 def settle_hike(cls, product):
     result = redpack_backends.settle_hike(product)
     if not result:
         return
     for x in result:
         order_id = OrderHelper.place_order(x['user'],
                                            order_type=u'加息',
                                            product_id=product.id,
                                            status=u'新建').id
         margin_keeper = MarginKeeper(user=x['user'], order_id=order_id)
         margin_keeper.hike_deposit(x['amount'],
                                    u"加息存入%s元" % x['amount'],
                                    savepoint=False)
         OrderHelper.update_order(Order.objects.get(pk=order_id),
                                  user=x['user'],
                                  status=u'成功',
                                  amount=x['amount'])
예제 #14
0
파일: php_utils.py 프로젝트: 859162000/wlba
def php_commission_one_pay_one(user, invite, product_id, level, amount,
                               earning):
    try:
        with transaction.atomic():
            income, create_flag = PhpIncome.objects.get_or_create(
                user=user,
                invite=invite,
                product_id=product_id,
                defaults={
                    'level': level,
                    'amount': amount,
                    'earning': earning,
                    'paid': False
                })
            income = PhpIncome.objects.select_for_update().get(id=income.id)
            if income and not income.paid:
                margin = MarginKeeper(user)
                if level == 1:
                    desc = u'月利宝一级淘金'
                elif level == 2:
                    desc = u'月利宝二级淘金'
                else:
                    desc = u'月利宝淘金'
                margin.deposit(earning, description=desc, catalog=u"全民淘金")

                income.order_id = margin.order_id
                income.paid = True
                income.save()
                return u'Success: [%s] introduced [%s] in [%s], level:%s, amount:%s, earning:%s' % (
                    user.id, invite.id, product_id, level, amount, earning)
            # Only for debug by hb on 2016-06-13
            if income and income.paid:
                return u'Ignore: [%s] introduced [%s] in [%s], level:%s, amount:%s, earning:%s' % (
                    user.id, invite.id, product_id, level, amount, earning)
            if not income:
                return u'NotFound: [%s] introduced [%s] in [%s], level:%s, amount:%s, earning:%s' % (
                    user.id, invite.id, product_id, level, amount, earning)
    except Exception, ex:
        return u'[%s] introduced [%s] in [%s], Except:(%s)' % (
            user.id, invite.id, product_id, ex)
예제 #15
0
 def rollback(self, description=u'', savepoint=True):
     with transaction.atomic(savepoint=savepoint):
         equity = P2PEquity.objects.select_for_update().filter(
             user=self.user, product=self.product).first()
         if not equity:
             raise P2PException(u'No equity available for user')
         if equity.confirm:
             raise P2PException(
                 u'The equity already confirmed, no way to revert')
         amount = equity.equity
         equity.delete()
         catalog = u'流标取消'
         record = self.__tracer(catalog, amount)
         user_margin_keeper = MarginKeeper(self.user, self.order_id)
         user_margin_keeper.unfreeze(amount, savepoint=False)
         # 流标要将红包退回账号
         p2precord = P2PRecord.objects.filter(user=self.user,
                                              product=self.product,
                                              catalog=u"申购")
         if p2precord:
             for p2p in p2precord:
                 result = redpack_backends.restore(p2p.order_id, p2p.amount,
                                                   p2p.user)
                 if result['ret_code'] == 0:
                     user_margin_keeper.redpack_return(
                         result['deduct'],
                         description=u"%s 流标 红包退回%s元" %
                         (self.product.short_name, result['deduct']))
         return record
예제 #16
0
파일: tasks.py 프로젝트: 859162000/wlba
def reward_earning(record, reward_user, got_amount, product, flag):
    from wanglibao_p2p.models import Earning
    from order.utils import OrderHelper
    from order.models import Order
    from django.forms import model_to_dict
    from wanglibao_margin.marginkeeper import MarginKeeper

    # 发放收益
    earning = Earning()
    earning.amount = got_amount
    earning.type = 'I'
    earning.product = product
    order = OrderHelper.place_order(reward_user,
                                    Order.ACTIVITY,
                                    u"邀请送收益活动赠送",
                                    earning=model_to_dict(earning))
    earning.order = order
    keeper = MarginKeeper(reward_user, order.pk)

    # 赠送活动描述
    desc = u'%s,邀请好友理财活动中,获赠%s元' % (reward_user.wanglibaouserprofile.name,
                                    got_amount)
    earning.margin_record = keeper.deposit(got_amount,
                                           description=desc,
                                           catalog=u"邀请赠送")
    earning.user = reward_user
    earning.save()

    if flag == 1:
        IntroducedByReward.objects.filter(id=record.id).update(
            checked_status=1, checked_at=timezone.now(), user_send_status=True)
    else:
        IntroducedByReward.objects.filter(id=record.id).update(
            checked_status=1,
            checked_at=timezone.now(),
            introduced_send_status=True)
예제 #17
0
파일: trade.py 프로젝트: 859162000/wlba
class P2PTrader(object):
    def __init__(self, product, user, order_id=None, request=None):
        self.user = user
        self.product = product

        if self.product.status != u"正在招标":
            raise P2PException(u'购买的标不在招标状态')

        self.request = request
        if order_id is None:
            self.order_id = OrderHelper.place_order(user,
                                                    order_type=u'产品申购',
                                                    product_id=product.id,
                                                    status=u'新建').id
        else:
            self.order_id = order_id
        self.margin_keeper = MarginKeeper(user=user, order_id=self.order_id)
        self.product_keeper = ProductKeeper(product, order_id=self.order_id)
        self.equity_keeper = EquityKeeper(user=user,
                                          product=product,
                                          order_id=self.order_id)
        if request:
            self.device = split_ua(request)
            self.device_type = self.device['device_type']
        else:
            self.device = split_ua(request)
            self.device_type = "pc"

    def purchase(self, amount, redpack=0, platform=u''):
        description = u'购买P2P产品 %s %s 份' % (self.product.short_name, amount)
        is_full = False
        product_balance_after = 0
        if self.user.wanglibaouserprofile.frozen:
            raise P2PException(u'用户账户已冻结,请联系客服')
        with transaction.atomic():
            if redpack:
                # 为防止用户同时打开两个浏览器同时使用加息券和红包,须先检测
                coupons = RedPackRecord.objects.filter(user=self.user, product_id=self.product.id) \
                    .filter(redpack__event__rtype='interest_coupon')
                if coupons:
                    raise P2PException(u'已经选择过加息券,不能重复或叠加使用')
                else:
                    this_redpack = RedPackRecord.objects.filter(
                        pk=redpack).first()
                    this_rtype = this_redpack.redpack.event.rtype
                    coupons = RedPackRecord.objects.filter(user=self.user, product_id=self.product.id) \
                        .exclude(redpack__event__rtype='interest_coupon')
                    if coupons and this_rtype == 'interest_coupon':
                        raise P2PException(u'红包和加息券不能同时叠加使用')

                redpack_order_id = OrderHelper.place_order(
                    self.user,
                    order_type=u'优惠券消费',
                    redpack=redpack,
                    product_id=self.product.id,
                    status=u'新建').id
                result = redpack_backends.consume(redpack, amount, self.user,
                                                  self.order_id,
                                                  self.device_type,
                                                  self.product.id)
                if result['ret_code'] != 0:
                    raise Exception, result['message']
                if result['rtype'] != 'interest_coupon':
                    red_record = self.margin_keeper.redpack_deposit(
                        result['deduct'],
                        u"购买P2P抵扣%s元" % result['deduct'],
                        order_id=redpack_order_id,
                        savepoint=False)
                OrderHelper.update_order(
                    Order.objects.get(pk=redpack_order_id),
                    user=self.user,
                    status=u'成功',
                    amount=amount,
                    deduct=result['deduct'],
                    redpack=redpack)

            product_record = self.product_keeper.reserve(amount,
                                                         self.user,
                                                         savepoint=False,
                                                         platform=platform)
            margin_record = self.margin_keeper.freeze(amount,
                                                      description=description,
                                                      savepoint=False)
            equity = self.equity_keeper.reserve(amount,
                                                description=description,
                                                savepoint=False)

            OrderHelper.update_order(Order.objects.get(pk=self.order_id),
                                     user=self.user,
                                     status=u'份额确认',
                                     amount=amount)

            product_balance_after = product_record.product_balance_after
            if product_balance_after <= 0:
                is_full = True

        # fix@chenweibin, add order_id
        # Modify by hb on 2015-11-25 : add "try-except"
        try:
            logger.debug("=20151125= decide_first.apply_async : [%s], [%s], [%s], [%s], [%s], [%s]" % \
                         (self.user.id, amount, self.device['device_type'], self.order_id, self.product.id, is_full) )
            tools.decide_first.apply_async(
                kwargs={
                    "user_id": self.user.id,
                    "amount": amount,
                    "device": self.device,
                    "order_id": self.order_id,
                    "product_id": self.product.id,
                    "is_full": is_full,
                    "product_balance_after": product_balance_after
                })
        except Exception, reason:
            logger.debug(
                "=20151125= decide_first.apply_async Except:{0}".format(
                    reason))
            pass

        try:
            logger.debug(
                "=20151125= CoopRegister.process_for_purchase : [%s], [%s]" %
                (self.user.id, self.order_id))
            CoopRegister(self.request).process_for_purchase(
                self.user, self.order_id)
        except Exception, reason:
            logger.debug(
                "=20151125= CoopRegister.process_for_purchase Except:{0}".
                format(reason))
            pass
예제 #18
0
def withdraw(request):
    amount = request.DATA.get("amount", "").strip()
    card_id = request.DATA.get("card_id", "").strip()
    vcode = request.DATA.get("validate_code", "").strip()
    if not amount or not card_id:
        return {"ret_code": 20061, "message": u"信息输入不完整"}

    user = request.user
    if not user.wanglibaouserprofile.id_is_valid:
        return {"ret_code": 20062, "message": u"请先进行实名认证"}

    if user.wanglibaouserprofile.frozen:
        return {"ret_code": 20072, "message": u"用户账户已冻结,请联系客服"}

    try:
        float(amount)
    except:
        return {"ret_code": 20063, 'message': u'金额格式错误'}
    amount = util.fmt_two_amount(amount)
    if len(str(amount)) > 20:
        return {"ret_code": 20064, 'message': u'金额格式错误,大于100元且为100倍数'}

    margin = user.margin.margin
    if amount > margin:
        return {"ret_code": 20065, 'message': u'余额不足'}

    phone = user.wanglibaouserprofile.phone
    status, message = validate_validation_code(phone, vcode)
    if status != 200:
        # Modify by hb on 2015-12-02
        #return {"ret_code": 20066, "message": u"验证码输入错误"}
        return {"ret_code": 20066, "message": message}

    card = Card.objects.filter(pk=card_id).first()
    if not card or card.user != user:
        return {"ret_code": 20067, "message": u"请选择有效的银行卡"}
    # 检测银行卡是否在黑名单中
    black_list = BlackListCard.objects.filter(card_no=card.no).first()
    if black_list and black_list.user != user:
        return {"ret_code": 20072, "message": u'银行卡号异常,请联系客服'}

    # 检查白名单
    white_list = WhiteListCard.objects.filter(user=user,
                                              card_no=card.no).first()
    if not white_list:
        # 增加银行卡号检测功能,检测多张卡
        card_count = Card.objects.filter(no=card.no).count()
        if card_count > 1:
            return {"ret_code": 20073, "message": u'银行卡号有多张重复,请联系客服'}

        # 检测银行卡在以前的提现记录中是否为同一个用户
        payinfo_record = PayInfo.objects.filter(
            card_no=card.no, type='W').order_by('-create_time').first()
        if payinfo_record:
            if payinfo_record.user != user:
                return {"ret_code": 20074, "message": u'银行卡号与身份信息不符,请联系客服'}

    # 计算提现费用 手续费 + 资金管理费
    bank = card.bank
    uninvested = user.margin.uninvested  # 充值未投资金额

    # 获取费率配置
    fee_misc = WithdrawFee()
    fee_config = fee_misc.get_withdraw_fee_config()

    # 检测提现最大最小金额
    if amount > fee_config.get('max_amount') or amount <= 0:
        return {"ret_code": 20068, 'message': u'提现金额超出最大提现限额'}
    if amount < fee_config.get('min_amount'):
        if amount != margin:
            return {
                "ret_code": 20069,
                'message':
                u'账户余额小于{}时需要一次性提完'.format(fee_config.get('min_amount'))
            }

    # 检测银行的单笔最大提现限额,如民生银行
    if bank and bank.withdraw_limit:
        bank_limit = util.handle_withdraw_limit(bank.withdraw_limit)
        bank_max_amount = bank_limit.get('bank_max_amount', 0)

        if bank_max_amount:
            if amount > bank_max_amount:
                return {"ret_code": 20070, 'message': u'提现金额超出银行最大提现限额'}

    # 获取计算后的费率
    fee, management_fee, management_amount = fee_misc.get_withdraw_fee(
        user, amount, margin, uninvested)

    # 实际提现金额
    actual_amount = amount - fee - management_fee
    if actual_amount <= 0:
        return {"ret_code": 20071, "message": u'实际到账金额为0,无法提现'}

    pay_info = PayInfo()
    pay_info.amount = actual_amount
    pay_info.fee = fee
    pay_info.management_fee = management_fee
    pay_info.management_amount = management_amount
    pay_info.total_amount = amount
    pay_info.type = PayInfo.WITHDRAW
    pay_info.user = user
    pay_info.card_no = card.no
    pay_info.account_name = user.wanglibaouserprofile.name
    pay_info.bank = card.bank
    pay_info.request_ip = util.get_client_ip(request)
    pay_info.status = PayInfo.ACCEPTED
    pay_info.channel = "app"

    try:
        order = OrderHelper.place_order(user,
                                        Order.WITHDRAW_ORDER,
                                        pay_info.status,
                                        pay_info=model_to_dict(pay_info))
        pay_info.order = order
        keeper = MarginKeeper(user, pay_info.order.pk)
        margin_record = keeper.withdraw_pre_freeze(
            amount, uninvested=management_amount)
        pay_info.margin_record = margin_record

        pay_info.save()
        return {
            "ret_code": 0,
            'message': u'提现成功',
            "amount": amount,
            "phone": phone,
            "bank_name": bank.name,
            "order_id": order.id
        }
    except Exception, e:
        pay_info.error_message = str(e)
        pay_info.status = PayInfo.FAIL
        pay_info.save()
        return {"ret_code": 20065, 'message': u'余额不足'}
예제 #19
0
def experience_repayment_plan():
    """
    体验标还款计划结算任务
    每天下午17:00分开始执行
    自动将当天17:00之间所有未结算的计划进行统一结算
    结算的利息自动计入用户的资金账户余额
    """
    print(u"Getting experience gold repayment plan to start!")
    now = datetime.now()
    # start = local_to_utc(datetime(now.year, now.month, now.day - 1, 17, 0, 0), 'normal')
    end = local_to_utc(datetime(now.year, now.month, now.day, 17, 0, 0),
                       'normal')

    phone_list = list()
    message_list = list()

    amortizations = ExperienceAmortization.objects.filter(
        settled=False).filter(term_date__lt=end)
    for amo_tmp in amortizations:

        is_commit = False
        with transaction.atomic(savepoint=True):
            # 锁定还款计划
            amo = ExperienceAmortization.objects.select_for_update().get(
                pk=amo_tmp.id)

            try:
                # Add by hb on 2016-06-08 : 避免体验金还款重复结算
                if amo.settled:
                    continue

                amo.settled = True
                amo.settlement_time = timezone.now()
                amo.save()

                if amo.interest > 0:
                    # 体验金利息计入用户账户余额
                    description = u"体验金利息入账:%s元" % amo.interest
                    user_margin_keeper = MarginKeeper(amo.user)
                    user_margin_keeper.deposit(amo.interest,
                                               description=description,
                                               catalog=u"体验金利息入账")

                    is_commit = True

            except Exception, e:
                logger.error(
                    u"experience repayment error, amortization id : %s , message: %s"
                    % (amo.id, e.message))

        # 发站内信,利息大于6元
        if amo_tmp.interest > 6 and is_commit:

            user_profile = amo_tmp.user.wanglibaouserprofile
            # 短信
            phone_list.append(user_profile.phone)
            message_list.append(
                messages.experience_amortize(user_profile.name,
                                             amo_tmp.interest))

            # 站内信
            title, content = messages.experience_amortize_msg(
                user_profile.name, amo_tmp.product.name,
                amo_tmp.product.period, timezone.now(), amo_tmp.interest)
            inside_message.send_one.apply_async(
                kwargs={
                    "user_id": amo_tmp.user.id,
                    "title": title,
                    "content": content,
                    "mtype": "amortize"
                })
예제 #20
0
파일: tasks.py 프로젝트: 859162000/wlba
def send_reward(start, end, amount_min, percent):
    from wanglibao_sms.tasks import send_messages
    from wanglibao_p2p.models import Earning
    from order.utils import OrderHelper
    from order.models import Order
    from django.forms import model_to_dict
    from wanglibao_margin.marginkeeper import MarginKeeper
    from wanglibao.templatetags.formatters import safe_phone_str
    from marketing.models import RewardRecord
    from decimal import Decimal

    start = datetime.strptime(start, '%Y-%m-%d')
    end = datetime.strptime(end, '%Y-%m-%d')

    # 审核通过,给用户发放奖励
    reward_type = u'邀请送收益'
    records = IntroducedByReward.objects.filter(
        checked_status=0,
        activity_start_at=local_to_utc(start, source_time='min'),
        activity_end_at=local_to_utc(end, source_time='max'),
        activity_amount_min=Decimal(amount_min),
        percent_reward=Decimal(percent),
    )

    if not records.exists():
        return

    for record in records:
        # with transaction.atomic():
        user, introduced_by, reward_type, got_amount, product = record.user, record.introduced_by_person, reward_type, record.introduced_reward, record.product

        reward = Reward.objects.filter(is_used=False, type=reward_type).first()

        # 发送短信
        # text_content = u"【网利宝】您在邀请好友送收益的活动中,获得%s元收益,收益已经发放至您的网利宝账户。请注意查收。" % got_amount
        # send_messages.apply_async(kwargs={
        #     "phones": [introduced_by.wanglibaouserprofile.phone],
        #     "messages": [text_content]
        # })

        # 发放收益
        earning = Earning()
        earning.amount = got_amount
        earning.type = 'I'
        earning.product = product
        order = OrderHelper.place_order(introduced_by,
                                        Order.ACTIVITY,
                                        u"邀请送收益活动赠送",
                                        earning=model_to_dict(earning))
        earning.order = order
        keeper = MarginKeeper(introduced_by, order.pk)

        # 赠送活动描述
        desc = u'%s,邀请好友首次理财活动中,活赠%s元' % (
            introduced_by.wanglibaouserprofile.name, got_amount)
        earning.margin_record = keeper.deposit(got_amount,
                                               description=desc,
                                               catalog=u"邀请首次赠送")
        earning.user = introduced_by
        earning.save()

        # 发放站内信
        message_content = u"您在邀请好友送收益的活动中,您的好友%s在活动期间完成首次投资,根据活动规则,您获得%s元收益。<br/>\
                  <a href='/accounts/home/' target='_blank'>查看账户余额</a><br/>\
                  感谢您对我们的支持与关注。<br/>\
                  网利宝" % (safe_phone_str(
            user.wanglibaouserprofile.phone), got_amount)
        RewardRecord.objects.create(user=introduced_by,
                                    reward=reward,
                                    description=message_content)
        inside_message.send_one.apply_async(
            kwargs={
                "user_id": introduced_by.id,
                "title": u"邀请送收益活动",
                "content": message_content,
                "mtype": "activity"
            })

        IntroducedByReward.objects.filter(id=record.id).update(
            checked_status=1)
예제 #21
0
파일: pay.py 프로젝트: 859162000/wlba
    def order_after_pay_succcess(self,
                                 amount,
                                 order_id,
                                 res_ip=None,
                                 res_content=None,
                                 request=None,
                                 need_bind_card=False):
        """
        处理订单和用户的账户
        :param amount:
        :param order_id:
        :param user_id:
        :param ip:
        :param res_content:
        :return:
        """
        # 参数校验
        pay_info = PayInfo.objects.select_for_update().filter(
            order_id=order_id).first()
        if not pay_info:
            # return {"ret_code":20131, "message":"order not exist", "amount": amount}
            raise ThirdPayError(20131, 'order not exist')
        if pay_info.status == PayInfo.SUCCESS:
            return {
                "ret_code": 0,
                "message": PayResult.DEPOSIT_SUCCESS,
                "amount": amount
            }
        if fmt_two_amount(pay_info.amount) != fmt_two_amount(amount):
            raise ThirdPayError(20132, PayResult.EXCEPTION)
        if pay_info.user_id != pay_info.user_id:
            raise ThirdPayError(20133, PayResult.EXCEPTION)

        # 更新pay_info和margin信息
        pay_info.error_message = ""
        if res_content:
            pay_info.response = res_content
        if res_ip:
            pay_info.response_ip = res_ip
        pay_info.fee = self.FEE
        keeper = MarginKeeper(pay_info.user, pay_info.order.pk)
        margin_record = keeper.deposit(amount)
        pay_info.margin_record = margin_record
        pay_info.status = PayInfo.SUCCESS
        pay_info.save()

        # 更新order信息
        # if len(pay_info.card_no) == 10:
        #     Card.objects.filter(user=pay_info.user, no__startswith=pay_info.card_no[:6], no__endswith=pay_info.card_no[-4:]).update(last_update=timezone.now(), is_bind_kuai=True)
        # else:
        #     Card.objects.filter(user=pay_info.user, no=pay_info.card_no).update(last_update=timezone.now(), is_bind_kuai=True)
        OrderHelper.update_order(pay_info.order,
                                 pay_info.user,
                                 pay_info=model_to_dict(pay_info),
                                 status=pay_info.status)
        # 绑卡
        if need_bind_card:
            self.add_card(pay_info.card_no, pay_info.bank, pay_info.user,
                          pay_info.channel)

        try:
            user = pay_info.user
            CoopRegister(request).process_for_recharge(user, order_id)
            # tools.deposit_ok(request.user.id, amount, pay_info.device, order_id)
            tools.deposit_ok.apply_async(
                kwargs={
                    "user_id": user.id,
                    "amount": amount,
                    "device": pay_info.device,
                    "order_id": order_id
                })
        except:
            logger.exception('recharge_call_back faile for ' + str(user) +
                             str(order_id))

        logger.critical("orderId:%s success" % order_id)
        rs = {
            "ret_code": 0,
            "message": "success",
            "amount": amount,
            "margin": margin_record.margin_current,
            "order_id": order_id
        }
        return rs
예제 #22
0
    def pre_pay(self, request, bank=None):
        """ 汇付天下直接进行邦卡支付,不能够获取验证码 """
        if not request.user.wanglibaouserprofile.id_is_valid:
            return {"ret_code": 20111, "message": "请先进行实名认证"}

        amount = request.DATA.get("amount", "").strip()
        card_no = request.DATA.get("card_no", "").strip()
        input_phone = request.DATA.get("phone", "").strip()
        gate_id = request.DATA.get("gate_id", "").strip()

        if not amount or not card_no or not gate_id:
            return {"ret_code": 20112, 'message': '信息输入不完整'}
        if len(card_no) > 10 and not input_phone:
            return {"ret_code": 20112, 'message': '信息输入不完整'}
        if card_no and len(card_no) == 10:
            return {'ret_code': 20013, 'message': '卡号格式不正确'}

        try:
            float(amount)
        except:
            return {"ret_code": 20114, 'message': '金额格式错误'}

        amount = fmt_two_amount(amount)

        user = request.user
        profile = user.wanglibaouserprofile

        bank = Bank.objects.filter(gate_id=gate_id).first()
        if not bank or not bank.huifu_bind_code.strip():
            return {"ret_code": 201151, "message": "不支持该银行"}

        if len(card_no) == 10:
            card = Card.objects.filter(user=user, no__startswith=card_no[:6], no__endswith=card_no[-4:]).first()
            card_no = card.no
        else:
            card = Card.objects.filter(no=card_no, user=user).first()

        if not card:
            card = self.bind_card_wlbk(user, card_no, bank, request)

        if not card:
            return {"ret_code": -1, "message": '银行卡不存在'}

        if bank and card and bank != card.bank:
            return {"ret_code": 201153, "message": "银行卡与银行不匹配"}
        if card and not card.is_bind_huifu:
            res = self.open_bind_card(user, bank, card)
            if res['ret_code'] != 0:
                return res

            card.is_bind_huifu = True
            card.save()

        try:
            pay_info = PayInfo()
            pay_info.amount = amount
            pay_info.total_amount = amount
            pay_info.type = PayInfo.DEPOSIT
            pay_info.status = PayInfo.INITIAL
            pay_info.user = user
            pay_info.channel = "huifu_bind"

            pay_info.request_ip = get_client_ip(request)
            order = OrderHelper.place_order(user, Order.PAY_ORDER, pay_info.status, pay_info=model_to_dict(pay_info))
            pay_info.order = order

            if card:
                pay_info.bank = card.bank
                pay_info.card_no = card.no
            else:
                pay_info.bank = bank
                pay_info.card_no = card_no

            pay_info.status = PayInfo.PROCESSING
            pay_info.account_name = profile.name
            pay_info.save()
            OrderHelper.update_order(order, user, pay_info=model_to_dict(pay_info), status=pay_info.status)

            # 充值
            req, res = self._card_pay_huifu(user=user, amount=pay_info.amount, card_no=card_no)

            pay_info.error_code = res['RespCode']
            pay_info.error_message = res['ErrMsg']
            pay_info.request = req
            pay_info.response = res
            pay_info.response_ip = get_client_ip(request)

            if res['RespCode'] != u'000000':
                pay_info.save()
                return {"ret_code": -3, "message": res['ErrMsg']}
            else:
                pay_info.fee = self.FEE
                keeper = MarginKeeper(pay_info.user, pay_info.order.pk)
                margin_record = keeper.deposit(amount)
                pay_info.margin_record = margin_record
                pay_info.status = PayInfo.SUCCESS
                pay_info.save()
                rs = {"ret_code": 0, "message": "success", "amount": amount, "margin": margin_record.margin_current}

            if rs['ret_code'] == 0:
                device = split_ua(request)
                try:
                    # fix@chenweibi, add order_id
                    tools.deposit_ok.apply_async(kwargs={"user_id": pay_info.user.id, "amount": pay_info.amount,
                                                         "device": device, "order_id": order.id})
                except:
                    pass

                # 充值成功后,更新本次银行使用的时间
                Card.objects.filter(user=pay_info.user, no=pay_info.card_no).update(last_update=timezone.now())

            OrderHelper.update_order(pay_info.order, pay_info.user, pay_info=model_to_dict(pay_info), status=pay_info.status)
            return rs
        except Exception, e:
            message = PayResult.RETRY
            pay_info.status = PayInfo.FAIL
            pay_info.error_message = str(e)
            pay_info.save()
            OrderHelper.update_order(order, request.user, pay_info=model_to_dict(pay_info), status=pay_info.status)
            return {"ret_code": "20119", "message": message}
예제 #23
0
파일: views.py 프로젝트: 859162000/wlba
    def post(self, request):
        action = request.POST.get('action')
        uuids_param = request.POST.get('transaction_uuids', '')
        uuids = re.findall(r'[\w\-_]+', uuids_param)
        payinfos = PayInfo.objects.filter(uuid__in=uuids,
                                          type='W').order_by('create_time')

        # These are the uuids exists in db for real
        uuids_param = ",".join([payinfo.uuid for payinfo in payinfos])

        if action == 'preview' or action is None:
            return self.render_to_response({
                'payinfos':
                payinfos,
                'total_amount':
                payinfos.aggregate(Sum("amount"))['amount__sum'],
                'transaction_uuids':
                uuids_param
            })
        elif action == 'confirm':
            for payinfo in payinfos:
                with transaction.atomic():
                    if payinfo.status != PayInfo.ACCEPTED and payinfo.status != PayInfo.PROCESSING:
                        logger.info(
                            "The withdraw status [%s] not in %s or %s, ignore it"
                            % (payinfo.status, PayInfo.ACCEPTED,
                               PayInfo.PROCESSING))
                        continue

                    amount = payinfo.amount
                    fee = payinfo.fee
                    management_fee = payinfo.management_fee
                    management_amount = payinfo.management_amount

                    marginKeeper = MarginKeeper(payinfo.user)
                    total_amount = amount + fee + management_fee
                    marginKeeper.withdraw_ack(total_amount,
                                              uninvested=management_amount)

                    payinfo.status = PayInfo.SUCCESS
                    payinfo.confirm_time = timezone.now()
                    payinfo.save()

                    # 给提现记录表中的信息同步进行确认,同时将提现的费用充值到网利宝的公司提现账户

                    if fee > 0 or management_fee > 0:
                        fee_total_amount = fee + management_fee
                        withdraw_card = WithdrawCard.objects.filter(
                            is_default=True).first()
                        withdraw_card.amount += fee_total_amount
                        withdraw_card.save()

                        # 将提现信息单独记录到提现费用记录表中
                        withdraw_card = WithdrawCard.objects.filter(
                            is_default=True).first()
                        if withdraw_card:
                            withdraw_card_record = WithdrawCardRecord()
                            withdraw_card_record.type = PayInfo.WITHDRAW
                            withdraw_card_record.amount = amount
                            withdraw_card_record.fee = fee
                            withdraw_card_record.management_fee = management_fee
                            withdraw_card_record.management_amount = management_amount
                            withdraw_card_record.withdrawcard = withdraw_card
                            withdraw_card_record.payinfo = payinfo
                            withdraw_card_record.user = payinfo.user
                            withdraw_card_record.status = PayInfo.SUCCESS
                            withdraw_card_record.message = u'用户提现费用存入'
                            withdraw_card_record.save()

                    # 取款确认时要检测该次提现是否是真正的在每个月的免费次数之内,如果是还需要将已扣除的费用返还给用户(仅限手续费)
                    give_back = False
                    if fee > 0:
                        fee_misc = WithdrawFee()
                        fee_config = fee_misc.get_withdraw_fee_config()
                        withdraw_count = fee_misc.get_withdraw_success_count(
                            payinfo.user)
                        free_times = fee_config['fee']['free_times_per_month']
                        if withdraw_count <= free_times:
                            give_back = True

                    if give_back:
                        # 1.给用户返还手续费
                        marginKeeper.deposit(
                            fee,
                            description=u'返还提现免费次数之内的手续费:{}元'.format(fee),
                            catalog=u"返还手续费")

                        # 2.从网利宝提现账户中减去手续费
                        withdraw_card = WithdrawCard.objects.filter(
                            is_default=True).first()
                        withdraw_card.amount -= fee
                        withdraw_card.save()

                        # 将提现信息单独记录到提现费用记录表中
                        withdraw_card_record = WithdrawCardRecord()
                        withdraw_card_record.type = PayInfo.WITHDRAW
                        withdraw_card_record.amount = fee
                        withdraw_card_record.fee = fee
                        withdraw_card_record.management_fee = 0
                        withdraw_card_record.management_amount = 0
                        withdraw_card_record.withdrawcard = withdraw_card
                        withdraw_card_record.payinfo = payinfo
                        withdraw_card_record.user = payinfo.user
                        withdraw_card_record.status = PayInfo.SUCCESS
                        withdraw_card_record.message = u'用户提现费用返还'
                        withdraw_card_record.save()

                    # 发站内信
                    title, content = messages.msg_withdraw_success(
                        timezone.now(), payinfo.amount)
                    inside_message.send_one.apply_async(
                        kwargs={
                            "user_id": payinfo.user_id,
                            "title": title,
                            "content": content,
                            "mtype": "withdraw"
                        })
                    send_messages.apply_async(
                        kwargs={
                            "phones":
                            [payinfo.user.wanglibaouserprofile.phone],
                            "messages": [
                                messages.withdraw_confirmed(
                                    payinfo.user.wanglibaouserprofile.name,
                                    amount)
                            ]
                        })
            return HttpResponse({u"所有的取款请求已经处理完毕 %s" % uuids_param})
예제 #24
0
파일: views.py 프로젝트: 859162000/wlba
    def post(self, request, *args, **kwargs):
        #result, message = verify_captcha(request.POST)
        #if not result:
        #    return self.render_to_response({
        #        'result': message
        #    })

        user = request.user
        if not user.wanglibaouserprofile.id_is_valid:
            return self.render_to_response({'result': u'请先进行实名认证'})
        if user.wanglibaouserprofile.frozen:
            return self.render_to_response(
                {'result': u'账户已冻结!请联系网利宝客服:4008-588-066'})
        phone = user.wanglibaouserprofile.phone
        code = request.POST.get('validate_code', '')
        status, message = validate_validation_code(phone, code)
        if status != 200:
            return self.render_to_response({
                # Modify by hb on 2015-12-02
                #'result': u'短信验证码输入错误'
                'result': message
            })

        result = PayResult.WITHDRAW_SUCCESS

        try:
            card_id = request.POST.get('card_id', '')
            card = Card.objects.get(pk=card_id, user=user)
            card_no = card.no

            # 检测银行卡是否在黑名单中
            black_list = BlackListCard.objects.filter(card_no=card_no).first()
            if black_list and black_list.user != user:
                raise AbnormalCardException

            # 检查白名单
            white_list = WhiteListCard.objects.filter(user=user,
                                                      card_no=card_no).first()
            if not white_list:
                # 增加银行卡号检测功能,检测多张卡
                card_count = Card.objects.filter(no=card_no).count()
                if card_count > 1:
                    raise ManyCardException

                # 检测银行卡在以前的提现记录中是否为同一个用户
                payinfo_record = PayInfo.objects.filter(
                    card_no=card_no).order_by('-create_time').first()
                if payinfo_record:
                    if payinfo_record.user != user:
                        raise AbnormalCardException

            amount_str = request.POST.get('amount', '')
            amount = decimal.Decimal(amount_str). \
                quantize(TWO_PLACES, context=decimal.Context(traps=[decimal.Inexact]))
            margin = user.margin.margin  # 账户余额
            uninvested = user.margin.uninvested  # 充值未投资金额

            # 获取费率配置
            fee_misc = WithdrawFee()
            fee_config = fee_misc.get_withdraw_fee_config()

            # 计算提现费用 手续费 + 资金管理费
            # 提现最大最小金额判断
            if amount > fee_config.get('max_amount') or amount <= 0:
                raise decimal.DecimalException
            if amount < fee_config.get('min_amount'):
                if amount != margin:
                    raise decimal.DecimalException
            # 获取计算后的费率
            fee, management_fee, management_amount = fee_misc.get_withdraw_fee(
                user, amount, margin, uninvested)

            actual_amount = amount - fee - management_fee  # 实际到账金额
            if actual_amount <= 0:
                raise decimal.DecimalException

            # 检测个别银行的单笔提现限额,如民生银行
            bank_limit = util.handle_withdraw_limit(card.bank.withdraw_limit)
            bank_max_amount = bank_limit.get('bank_max_amount', 0)
            if bank_max_amount:
                if amount > bank_max_amount:
                    raise decimal.DecimalException

            pay_info = PayInfo()
            pay_info.amount = actual_amount
            pay_info.fee = fee
            pay_info.management_fee = management_fee
            pay_info.management_amount = management_amount
            pay_info.total_amount = amount
            pay_info.type = PayInfo.WITHDRAW
            pay_info.user = user
            pay_info.card_no = card.no
            pay_info.account_name = user.wanglibaouserprofile.name
            pay_info.bank = card.bank
            pay_info.request_ip = get_client_ip(request)
            pay_info.status = PayInfo.ACCEPTED

            order = OrderHelper.place_order(user,
                                            Order.WITHDRAW_ORDER,
                                            pay_info.status,
                                            pay_info=model_to_dict(pay_info))

            pay_info.order = order
            keeper = MarginKeeper(user, pay_info.order.pk)
            margin_record = keeper.withdraw_pre_freeze(
                amount, uninvested=management_amount)
            pay_info.margin_record = margin_record

            pay_info.save()
            try:
                device = split_ua(request)
            except:
                device = {'device_type': 'pc'}

            name = user.wanglibaouserprofile.name or u'用户'
            withdraw_submit_ok.apply_async(
                kwargs={
                    "user_id": user.id,
                    "user_name": name,
                    "phone": user.wanglibaouserprofile.phone,
                    "amount": amount,
                    "bank_name": card.bank.name,
                    "order_id": order.id,
                    "device": device
                })
        except decimal.DecimalException:
            result = u'提款金额在0~{}之间'.format(fee_config.get('max_amount'))
        except Card.DoesNotExist:
            result = u'请选择有效的银行卡'
        except ManyCardException:
            result = u'银行卡号存在重复,请尝试其他银行卡号码,如非本人操作请联系客服'
        except AbnormalCardException:
            result = u'银行卡号与身份信息存在异常, 如非本人操作请联系客服'
        except MarginLack as e:
            result = u'余额不足'
            pay_info.error_message = str(e)
            pay_info.status = PayInfo.FAIL
            pay_info.save()

        # return self.render_to_response({
        #     'result': result
        # })
        return HttpResponseRedirect(
            reverse('withdraw-complete-result', kwargs={'result': result}))
예제 #25
0
    def amortize(self, amortization, savepoint=True):
        with transaction.atomic(savepoint=savepoint):
            if amortization.settled:
                raise P2PException('amortization %s already settled.' %
                                   amortization)
            sub_amortizations = amortization.subs.all()
            description = unicode(amortization)
            catalog = u'分期还款'
            product = amortization.product

            matches = re.search(u'日计息', product.pay_method)
            if matches and matches.group():
                pname = u"%s,期限%s天" % (product.name, product.period)
            else:
                pname = u"%s,期限%s个月" % (product.name, product.period)

            phone_list = list()
            message_list = list()
            settled_sub_amos = list()
            for sub_amo in sub_amortizations:
                user_margin_keeper = MarginKeeper(sub_amo.user)
                user_margin_keeper.amortize(sub_amo.principal,
                                            sub_amo.interest,
                                            sub_amo.penal_interest,
                                            sub_amo.coupon_interest,
                                            savepoint=False,
                                            description=description)

                sub_amo.settled = True
                sub_amo.settlement_time = timezone.now()
                sub_amo.save()

                amo_amount = sub_amo.principal + sub_amo.interest + sub_amo.penal_interest + sub_amo.coupon_interest

                # 加入重复回款的用户还需要扣回的金额及扣款操作
                try:
                    repeat_user = RepeatPaymentUser.objects.select_for_update()\
                        .filter(user_id=sub_amo.user.id, amount__gt=0).first()
                    if repeat_user:
                        repeat_amount = repeat_user.amount
                        # if repeat_amount > 0:
                        # 判断是否每天从回款中扣款
                        is_every_day = True
                        if not repeat_user.is_every_day:
                            product_ids = repeat_user.product_ids.split(',')
                            product_ids = [
                                int(p_id) for p_id in product_ids
                                if p_id.strip() != ''
                            ]
                            # 判断当期还款的产品id是否在用户新购标的id中, 不在说明该标不用扣款
                            if product.id not in product_ids:
                                is_every_day = False

                        if is_every_day:
                            # 判断剩余应扣金额是否大于等于本期回款本息之合, 大于等于,则扣本息,否则扣剩余应扣金额
                            if repeat_amount >= amo_amount:
                                reduce_amount = amo_amount
                                reduce_amount_current = repeat_amount - amo_amount  # 剩余应扣金额-本次扣除的本息之合
                            else:
                                reduce_amount = repeat_amount
                                reduce_amount_current = 0

                            print(
                                "repeat_amount: %s, amo_amount: %s, type1:%s, type2:%s"
                                % (repeat_amount, amo_amount,
                                   type(repeat_amount), type(amo_amount)))

                            # 减账户余额
                            user_margin_keeper.reduce_margin(
                                reduce_amount, u'系统重复回款扣回%s元' % reduce_amount)

                            # 更新剩余应扣金额
                            repeat_user.amount = reduce_amount_current
                            repeat_user.save()

                            # 记录扣款流水
                            repeat_record = RepeatPaymentUserRecords(
                                user_id=sub_amo.user.id,
                                name=sub_amo.user.wanglibaouserprofile.name,
                                phone=sub_amo.user.wanglibaouserprofile.phone,
                                amount=reduce_amount,
                                amount_current=reduce_amount_current,
                                description=description)
                            repeat_record.save()
                except Exception:
                    logger.exception('err')
                    logger.error("用户扣款失败,用户id:[%s], 回款本息合计:[%s]" %
                                 (sub_amo.user, amo_amount))
                    pass

                try:
                    phone_list.append(sub_amo.user.wanglibaouserprofile.phone)
                    message_list.append(
                        messages.product_amortize(
                            sub_amo.user.wanglibaouserprofile.name,
                            amortization.product,
                            # sub_amo.settlement_time,
                            amo_amount))
                    title, content = messages.msg_bid_amortize(
                        pname, timezone.now(), amo_amount)
                    inside_message.send_one.apply_async(
                        kwargs={
                            "user_id": sub_amo.user.id,
                            "title": title,
                            "content": content,
                            "mtype": "amortize"
                        })
                except:
                    logger.debug("")

                self.__tracer(catalog, sub_amo.user, sub_amo.principal,
                              sub_amo.interest, sub_amo.penal_interest,
                              amortization, description,
                              sub_amo.coupon_interest)

                # 标的每一期还款完成后,检测该用户还款的本金是否有符合活动的规则,有的话触发活动规则
                try:
                    if sub_amo.principal > 0:
                        # activity_backends.check_activity(sub_amo.user, 'repaid', 'pc', sub_amo.principal, product.id)
                        check_activity_task.apply_async(kwargs={
                            "user_id":
                            sub_amo.user.id,
                            "trigger_node":
                            'repaid',
                            "device_type":
                            'pc',
                            "amount":
                            sub_amo.principal,
                            "product_id":
                            product.id,
                        },
                                                        queue='celery02')
                except Exception:
                    logger.debug(
                        "check activity on repaid, user: {}, principal: {}, product_id: {}"
                        .format(sub_amo.user.id, sub_amo.principal,
                                product.id))

                try:
                    weixin_user = WeixinUser.objects.filter(
                        user=sub_amo.user).first()

                    if weixin_user and weixin_user.subscribe:
                        now = datetime.now().strftime('%Y年%m月%d日 %H:%M:%S')
                        sentTemplate.apply_async(kwargs={
                            "kwargs":
                            json.dumps({
                                "openid": weixin_user.openid,
                                "template_id":
                                PRODUCT_AMORTIZATION_TEMPLATE_ID,
                                "keyword1": product.name,
                                "keyword2": "%s 元" % str(amo_amount),
                                "keyword3": now,
                            })
                        },
                                                 queue='celery02')

                except Exception, e:
                    logger.debug(
                        ">>>> weixin msg send err, user_id:[%s], [%s] " %
                        sub_amo.user.id, e)
                    pass

                # 添加还款用户到渠道通知列表 @chenwb
                try:
                    settled_sub_amos.append({
                        'id':
                        sub_amo.id,
                        'user':
                        sub_amo.user.id,
                        'product':
                        product.id,
                        'term':
                        sub_amo.term,
                        'settled':
                        sub_amo.settled,
                        'term_date':
                        sub_amo.term_date.strftime('%Y-%m-%d %H:%M:%S'),
                        'settlement_time':
                        sub_amo.settlement_time.strftime('%Y-%m-%d %H:%M:%S'),
                        'principal':
                        float(sub_amo.principal),
                        'interest':
                        float(sub_amo.interest),
                        'penal_interest':
                        float(sub_amo.penal_interest),
                        'coupon_interest':
                        float(sub_amo.coupon_interest),
                        'description':
                        sub_amo.description,
                    })
                except:
                    pass

            amortization.settled = True
            amortization.save()
            catalog = u'还款入账'

            send_messages.apply_async(kwargs={
                "phones": phone_list,
                "messages": message_list
            })

            self.__tracer(catalog, None, amortization.principal,
                          amortization.interest, amortization.penal_interest,
                          amortization)

            # 向渠道中心发送还款用户列表通知 @chenwb
            # Comment by hb on 2016-05-13
            try:
                if settled_sub_amos:
                    from .tasks import coop_amortizations_push
                    coop_amortizations_push.apply_async(kwargs={
                        'amortizations': settled_sub_amos,
                        'product_id': product.id,
                        'amo_act': 'amortize'
                    },
                                                        queue='celery02')
            except:
                pass
예제 #26
0
        pay_info.response_ip = util.get_client_ip(request)

        if not pay_info.bank and "bank" in params:
            bank = Bank.objects.filter(name=params['bank']).first()
            if bank:
                pay_info.bank = bank

        if pay_info.amount != amount:
            pay_info.status = PayInfo.FAIL
            pay_info.error_message += u' 金额不匹配'
            logger.error("orderId:%s amount:%s, response amount:%s" % (orderId, pay_info.amount, amount))
            rs = {"ret_code":20086, "message":PayResult.EXCEPTION}
        else:
            if params['status'] == 1:
                pay_info.fee = self.FEE
                keeper = MarginKeeper(pay_info.user, pay_info.order.pk)
                margin_record = keeper.deposit(amount)
                pay_info.margin_record = margin_record
                pay_info.status = PayInfo.SUCCESS
                logger.error("orderId:%s yeepay response status:%s" % (orderId, params['status']))
                rs = {"ret_code":0, "message":"success", "amount":amount, "uid":pay_info.user.id}
            else:
                pay_info.status = PayInfo.FAIL
                logger.error("orderId:%s yeepay response status: %s" % (orderId, params['status']))
                rs = {"ret_code":20087, "message":PayResult.DEPOSIT_FAIL}

        pay_info.save()
        if rs['ret_code'] == 0:
            device = split_ua(request)
            try:
                # fix@chenweibi, add order_id
예제 #27
0
    def handle_pay_result(cls, request):
        # TODO Add a log

        flag = False

        order_id = request.POST.get('OrdId', '')
        try:
            pay_info = PayInfo.objects.select_for_update().get(pk=order_id)
        except PayInfo.DoesNotExist:
            logger.warning('Order not found, order id: ' + order_id + ', response: ' + request.body)
            return PayResult.EXCEPTION

        if pay_info.status == PayInfo.SUCCESS:
            return PayResult.DEPOSIT_SUCCESS

        amount = request.POST.get('OrdAmt', '')
        code = request.POST.get('RespCode', '')
        message = request.POST.get('ErrMsg', '')
        pay_info.error_code = code
        pay_info.error_message = message
        pay_info.response = request.body
        pay_info.response_ip = get_client_ip(request)

        result = u''
        try:
            pay = HuifuPay()
            if pay.verify_sign(request.POST.dict(), HuifuPay.PAY_FIELDS):
                if pay_info.amount != decimal.Decimal(amount):
                    pay_info.status = PayInfo.FAIL
                    pay_info.error_message += u' 金额不匹配'
                    logger.error('Amount mismatch, order id: %s request amount: %f response amount: %s',
                                 order_id, float(pay_info.amount), amount)
                    result = PayResult.EXCEPTION
                else:
                    if code == '000000':
                        keeper = MarginKeeper(pay_info.user, pay_info.order.pk)
                        margin_record = keeper.deposit(amount)
                        pay_info.margin_record = margin_record
                        pay_info.status = PayInfo.SUCCESS
                        result = PayResult.DEPOSIT_SUCCESS
                        phone = pay_info.user.wanglibaouserprofile.phone

                        flag = True
                    else:
                        pay_info.status = PayInfo.FAIL
                        result = PayResult.DEPOSIT_FAIL
            else:
                pay_info.error_message = 'Invalid signature. Order id: ' + order_id
                logger.error(pay_info.error_message)
                pay_info.status = PayInfo.EXCEPTION
                result = PayResult.EXCEPTION
        except (socket.error, SignException) as e:
            pay_info.error_message = str(e)
            pay_info.status = PayInfo.EXCEPTION
            logger.fatal('sign error! order id: ' + order_id + ' ' + str(e))
            result = PayResult.EXCEPTION

        pay_info.save()

        if flag:
            device = split_ua(request)
            try:
                # fix@chenweibi, add order_id
                tools.deposit_ok.apply_async(kwargs={"user_id": pay_info.user.id, "amount": pay_info.amount,
                                                     "device": device, "order_id": pay_info.order_id})
                CoopRegister(request).process_for_recharge(pay_info.user, pay_info.order_id)
            except:
                pass

        OrderHelper.update_order(pay_info.order, pay_info.user, pay_info=model_to_dict(pay_info), status=pay_info.status)
        return result
예제 #28
0
    def post(self, request):
        user = request.user
        now = timezone.now()
        start_dt = local_to_utc(datetime(2016, 6, 7), 'min')
        user_joined = user.date_joined  # 用户注册时间
        device = split_ua(request)
        device_type = decide_device(device['device_type'])
        purchase_code = 'experience_purchase'

        experience_product = ExperienceProduct.objects.filter(
            isvalid=True).first()
        if not experience_product:
            return Response({'ret_code': 30001, 'message': u'体验标有误,请重试'})

        total_amount = 0
        total_amount_tmp = 0

        # 查询用户符合条件的理财金记录
        with transaction.atomic(savepoint=True):
            # 锁表,主要用来锁定体验金投资时的动作
            purchase_lock_record = ExperiencePurchaseLockRecord.objects.select_for_update().\
                filter(user=user, purchase_code=purchase_code).first()

            if not purchase_lock_record:
                # 没有记录时创建一条
                try:
                    purchase_lock_record = ExperiencePurchaseLockRecord.objects.create(
                        user=user,
                        purchase_code=purchase_code,
                        purchase_times=0)
                except Exception:
                    logger.exception(
                        "Error: experience purchase err, user: %s, phone: %s" %
                        (user.id, user.wanglibaouserprofile.phone))
                    return Response({
                        'ret_code': 30003,
                        'message': u'体验金投资失败,请重试'
                    })

            experience_record = ExperienceEventRecord.objects.filter(user=user, apply=False) \
                .filter(event__invalid=False, event__available_at__lt=now, event__unavailable_at__gt=now)\
                .select_related('event')

            records_ids = ''
            if experience_record:
                catalog = u'购买体验标'

                for i in experience_record:
                    total_amount_tmp += i.event.amount

                buy_p2p = P2PRecord.objects.filter(user_id=user.id).exists()
                buy_count = MarginRecord.objects.filter(
                    user_id=user.id, catalog=catalog).count()
                if not buy_p2p:
                    if user_joined > start_dt:
                        # 如果查询到已经购买过至少 1 次体验标,则不再检测账户余额
                        if buy_count == 0:
                            if total_amount_tmp >= 28888 and user.margin.margin < 1:
                                return Response({
                                    'ret_code': 30009,
                                    'message': u'账户余额不足,请先充值'
                                })

                for record in experience_record:
                    event = record.event
                    total_amount += event.amount
                    records_ids += str(record.id) + ','

                    record.apply = True
                    record.apply_amount = event.amount
                    record.apply_at = timezone.now()
                    record.apply_platform = device_type
                    record.save()

                terms = get_amortization_plan(u'日计息一次性还本付息').generate(
                    total_amount,
                    experience_product.expected_earning_rate / 100.0,
                    timezone.now(), experience_product.period)

                for index, term in enumerate(terms['terms']):
                    amortization = ExperienceAmortization()
                    amortization.product = experience_product
                    amortization.user = user
                    amortization.principal = term[1]  # 本金
                    amortization.interest = term[2]  # 利息
                    amortization.term = index + 1  # 期数
                    amortization.description = u'第%d期' % (index + 1)
                    amortization.term_date = term[6] - timedelta(days=1)

                    amortization.save()

                # 从账户中扣除 1 元 (没有购买过体验标的情况)
                if not buy_p2p:
                    if user_joined > start_dt:
                        if total_amount >= 28888 and buy_count == 0:
                            amount = 1.00
                            order_id = OrderHelper.place_order(
                                user, order_type=catalog, status=u'新建').id
                            margin_keeper = MarginKeeper(user=user,
                                                         order_id=order_id)
                            margin_keeper.reduce_margin_common(
                                amount, catalog=catalog, description=catalog)

                # 更新当前的一组流水id
                purchase_lock_record.purchase_times += 1
                purchase_lock_record.description = records_ids
                purchase_lock_record.save()

                term_date = amortization.term_date
                interest = amortization.interest

                return Response({
                    'ret_code': 0,
                    'data': {
                        'amount': total_amount,
                        'term_date': term_date.strftime("%Y-%m-%d"),
                        'interest': interest
                    }
                })

            else:
                return Response({
                    'ret_code': 30002,
                    'message': u'没有体验金记录,无法购买体验标'
                })
예제 #29
0
파일: tasks.py 프로젝트: 859162000/wlba
def build_earning(product_id):

    p2p = P2PProduct.objects.select_related('activity__rule').get(
        pk=product_id)

    num = Earning.objects.filter(product=p2p).count()
    if num > 0:
        return

    #按用户汇总某个标的收益
    earning = P2PRecord.objects.values('user').annotate(
        sum_amount=Sum('amount')).filter(product=p2p, catalog=u'申购')

    phone_list = []
    earning_list = []
    rule = p2p.activity.rule

    unit = period_unit(p2p.pay_method)

    #把收益数据插入earning表内
    for obj in earning:
        # bind = Binding.objects.filter(user_id=obj.get('user')).first()
        # if bind and bind.isvip:

        earning = Earning()
        amount = rule.get_earning(obj.get('sum_amount'), p2p.period,
                                  p2p.pay_method)
        earning.amount = amount
        earning.type = 'D'
        earning.product = p2p
        user = User.objects.get(pk=obj.get('user'))
        order = OrderHelper.place_order(user,
                                        Order.ACTIVITY,
                                        u"活动赠送",
                                        earning=model_to_dict(earning))
        earning.order = order

        keeper = MarginKeeper(user, order.pk)

        #赠送活动描述
        desc = u'%s,%s赠送%s%s' % (p2p.name, p2p.activity.name,
                                 p2p.activity.rule.rule_amount * 100, '%')
        earning.margin_record = keeper.deposit(amount,
                                               description=desc,
                                               catalog=u"活动赠送")
        earning.user = user

        #earning.save()

        earning_list.append(earning)
        phone_list.append(user.wanglibaouserprofile.phone)

        earning_time = timezone.localtime(
            timezone.now()).strftime("%Y-%m-%d %H:%M:%S")
        title, content = messages.msg_bid_earning(p2p.name, p2p.activity.name,
                                                  p2p.period, earning_time,
                                                  rule.percent_text, amount,
                                                  unit)
        inside_message.send_one.apply_async(
            kwargs={
                "user_id": obj.get('user'),
                "title": title,
                "content": content,
                "mtype": "activity"
            })

    #发送活动赠送短信
    # send_messages.apply_async(kwargs={
    #                 "phones": phone_list,
    #                 "messages": [messages.earning_message(rule.percent_text)]
    #             })

    Earning.objects.bulk_create(earning_list)
예제 #30
0
    def prepayment(self, penal_interest, repayment_type, payment_date, savepoint=True):
        """
                #1. 拿到当期未还款计划
                #1.11 如果是按期提前还款
                #1.12 利息 = 当期利息
                #1.21 如果是按日提前还款
                #1.22 利息 = 年利率/360*计息天数*本金
                #2. 拿到此标的年华收益
                #3. 计算日收益
                #4. 计算当期未计息天数
        """
        pname = ''
        amortization_records_tmp = list()
        phone_list = list()
        message_list = list()
        with transaction.atomic(savepoint=savepoint):
            amortization = ProductAmortization.objects.select_for_update().get(id=self.amortization.id)
            if amortization.settled:
                raise PrepaymentException()
            # 1.生成产品提前还款记录
            # amortization = self.amortization
            product_record = self.get_product_repayment(penal_interest, repayment_type, payment_date)
            order_id = OrderHelper.place_order(None, order_type=self.catalog, product_id=self.product.id, status=u'新建').id
            product_record.order_id = order_id

            amortization_records = list()
            # 用户还款计划
            user_amortizations = amortization.subs.all().select_related('user__wanglibaouserprofile')

            product = amortization.product
            import re
            matches = re.search(u'日计息', product.pay_method)
            if matches and matches.group():
                pname = u"%s,期限%s天" % (product.name, product.period)
            else:
                pname = u"%s,期限%s个月" % (product.name, product.period)

            for user_amortization in user_amortizations:
                logger.error("提前还款用户: [%s], [%s]" % (user_amortization.user.id, user_amortization.user.wanglibaouserprofile.phone))
                # 计算最终计算提前还款的本金, 利息, 罚息, 加息
                user_record = self.get_user_repayment(user_amortization, penal_interest, repayment_type, payment_date)
                logger.error("新的本金: [%s], 利息:[%s], 加息:[%s], repayment_type:[%s], payment_date:[%s]" % (
                    user_record.principal, user_record.interest, user_record.coupon_interest, repayment_type, payment_date))

                user_margin_keeper = MarginKeeper(user_record.user)
                # 提前还款需要将加息金额还给用户(重新计算后的该用户所用加息券的加息金额)
                user_margin_keeper.amortize(user_record.principal, user_record.interest, user_record.penal_interest,
                                            user_record.coupon_interest, savepoint=False, description=self.description)

                order_id = OrderHelper.place_order(user_record.user, order_type=self.catalog, product_id=self.product.id, status=u'新建').id

                user_record.order_id = order_id
                user_record.amortization = amortization

                amortization_records.append(user_record)
                amortization_records_tmp.append(user_record)  # 发消息临时list变量(不包含product_record)
                logger.error("order_id: %s" % order_id)

            amortization_records.append(product_record)

            AmortizationRecord.objects.bulk_create(amortization_records)

            ProductAmortization.objects.filter(product=self.product, settled=False)\
                .update(settled=True, settlement_time=timezone.now())
            UserAmortization.objects.filter(product_amortization__product=self.product, settled=False)\
                .update(settled=True, settlement_time=timezone.now())
            ProductKeeper(self.product).finish(None)

        # 将提前还款的消息发送放到事务外边
        for user_record in amortization_records_tmp:
            try:
                # 提前还款短信
                # 提前还款金额 = 本金 + 利息 + 罚息 + 加息
                amo_amount = user_record.principal + user_record.interest + \
                    user_record.penal_interest + user_record.coupon_interest
                user = user_record.user
                user_profile = user.wanglibaouserprofile
                phone_list.append(user_profile.phone)
                message_list.append(messages.product_prepayment(user_profile.name,
                                                                amortization.product,
                                                                amo_amount))

                # 标的每一期还款完成后,检测该用户还款的本金是否有符合活动的规则,有的话触发活动规则
                try:
                    if user_record.principal > 0:
                        # activity_backends.check_activity(user, 'repaid', 'pc', user_record.principal, product.id)
                        check_activity_task.apply_async(kwargs={
                            "user_id": user.id,
                            "trigger_node": 'repaid',
                            "device_type": 'pc',
                            "amount": user_record.principal,
                            "product_id": product.id
                        }, queue='celery02')
                except Exception:
                    logger.exception("==提前还款==活动检测==")
                    logger.debug("提前还款, user: {}, principal: {}, product_id: {}".format(
                        user, user_record.principal, product.id
                    ))
                try:
                    # 提前还款站内信
                    title, content = messages.msg_bid_prepayment(pname, timezone.now(), amo_amount)
                    inside_message.send_one.apply_async(kwargs={
                        "user_id": user.id,
                        "title": title,
                        "content": content,
                        "mtype": "amortize"
                    })
                except Exception, e:
                    logger.exception("==提前还款==站内信==")
                    logger.debug(("user:%s====提前还款==站内信==" % user.id) + traceback.format_exc())
                try:
                    weixin_user = WeixinUser.objects.filter(user=user).first()

                    if weixin_user and weixin_user.subscribe:
                        now = datetime.now().strftime('%Y年%m月%d日 %H:%M:%S')
                        sentTemplate.apply_async(kwargs={
                            "kwargs": json.dumps({
                                "openid": weixin_user.openid,
                                "template_id": PRODUCT_AMORTIZATION_TEMPLATE_ID,
                                "keyword1": product.name,
                                "keyword2": "%s 元" % str(amo_amount),
                                "keyword3": now,
                            })
                        }, queue='celery02')
                except Exception, e:
                    logger.exception("==提前还款==微信模板==")
                    logger.debug(("user:%s====提前还款==微信模板==" % user.id) + traceback.format_exc())