private static void CheckTimeoutProject(TimerMsg.Type timerType, bool onTime)
        {
            if (timerType != TimerMsg.Type.AutoRepayTimer)
            {
                return;
            }

            var db = new Agp2pDataContext();
            // 活期项目不会过时
            var timeoutProjects = db.li_projects.Where(
                p => p.dt_article_category.call_index != "huoqi" &&
                p.status == (int)Agp2pEnums.ProjectStatusEnum.Financing && p.publish_time != null)
                                  .AsEnumerable()
                                  .Where(p => p.publish_time.Value.AddDays(p.financing_day).Date <= DateTime.Today).ToList();

            if (!timeoutProjects.Any())
            {
                return;
            }

            timeoutProjects.ForEach(p =>
            {
                p.status = (int)Agp2pEnums.ProjectStatusEnum.FinancingTimeout;
                db.AppendAdminLog("AutoSetProjectTimeout", string.Format("项目 {0} 募集已超时", p.title));
            });
            db.SubmitChanges();

            timeoutProjects.ForEach(p =>
            {
                MessageBus.Main.Publish(new ProjectFinancingTimeoutMsg(p.id)); // 广播项目融资超时的消息
            });
        }
示例#2
0
        public static void CheckStaticProjectWithdrawOvertime(TimerMsg.Type timerType, bool onTime)
        {
            if (timerType != TimerMsg.Type.AutoRepayTimer)
            {
                return;
            }

            var context = new Agp2pDataContext();
            // 申请时间超过 2 日 / 到达还款日,则取消债权转让申请
            var withdrawOvertimeClaims = context.li_claims
                                         .Where(c => c.status == (int)Agp2pEnums.ClaimStatusEnum.NeedTransfer && c.projectId == c.profitingProjectId &&
                                                !c.Children.Any())
                                         .AsEnumerable().Where(c =>
            {
                var nextRepayDate = c.li_projects.li_repayment_tasks.FirstOrDefault(ta => ta.IsUnpaid())?.should_repay_time.Date;
                if (nextRepayDate != null && nextRepayDate.Value <= DateTime.Today)
                {
                    return(true);
                }
                return(c.createTime < DateTime.Now.AddDays(-2));
            }).ToList();

            if (!withdrawOvertimeClaims.Any())
            {
                return;
            }

            withdrawOvertimeClaims.ForEach(c => TransactionFacade.StaticClaimWithdrawCancel(context, c.id, false));
            context.AppendAdminLog("StaticWithdraw", "取消超时的定期债权转让申请:" + withdrawOvertimeClaims.Count);
            context.SubmitChanges();
        }
示例#3
0
        public static void GenerateHuoqiRepaymentTask(TimerMsg.Type timerType, bool onTime)
        {
            if (timerType != TimerMsg.Type.LoanerRepayTimer)
            {
                return;
            }

            var context = new Agp2pDataContext();
            var today   = DateTime.Today;

            var huoqiProjects = context.li_projects.Where(p =>
                                                          p.status == (int)Agp2pEnums.ProjectStatusEnum.Financing &&
                                                          p.dt_article_category.call_index == "huoqi").ToList();

            var dailyRepayments = huoqiProjects.SelectMany(p =>
            {
                // 检查今日是否已经生成过还款计划
                var lastRepaymentTask = context.li_repayment_tasks.Where(ta => ta.project == p.id)
                                        .OrderByDescending(ta => ta.should_repay_time)
                                        .FirstOrDefault();
                if (lastRepaymentTask != null && today < lastRepaymentTask.should_repay_time)
                {
                    return(Enumerable.Empty <li_repayment_tasks>());
                }

                // 如果是今天/昨日才投的活期标,则不返利
                // 如果前日有 不可转让/可转让 的债权,则会产生收益(提现后不再产生收益)
                var shouldRepayTo = p.li_claims_profiting.Where(c => c.IsProfiting()).ToList();
                if (!shouldRepayTo.Any())
                {
                    return(Enumerable.Empty <li_repayment_tasks>());
                }
                return(new[]
                {
                    new li_repayment_tasks
                    {
                        should_repay_time = today.AddHours(15),
                        repay_principal = 0,
                        repay_interest = Math.Round(1m / TransactionFacade.HuoqiProjectProfitingDay * p.profit_rate_year / 100 * shouldRepayTo.Sum(c => c.principal), 2),
                        project = p.id,
                        status = (byte)Agp2pEnums.RepaymentStatusEnum.Unpaid,
                        term = (short)((p.li_repayment_tasks.LastOrDefault()?.term ?? 0) + 1)
                    }
                });
            }).ToList();

            if (!dailyRepayments.Any())
            {
                return;
            }

            context.li_repayment_tasks.InsertAllOnSubmit(dailyRepayments);

            context.AppendAdminLog("Huoqi",
                                   "自动生成今天 " + dailyRepayments.Count + " 个活期项目的还款计划,利润总计:" +
                                   dailyRepayments.Aggregate(0m, (sum, tasks) => sum + tasks.repay_interest).ToString("c"));
            context.SubmitChanges();
        }
示例#4
0
        public static void HandleTimerMsg(TimerMsg.Type timerName, bool startUp)
        {
            if (timerName != TimerMsg.Type.AutoRepayTimer)
            {
                return;
            }

            var repayTime = DateTime.Now;
            var context   = new Agp2pDataContext();

            // 找出过期的券并标记为过期
            context.li_activity_transactions.Where(a =>
                                                   a.activity_type == (int)Agp2pEnums.ActivityTransactionActivityTypeEnum.TrialTicket &&
                                                   a.status == (int)Agp2pEnums.ActivityTransactionStatusEnum.Acting)
            .AsEnumerable()
            .ForEach(atr => new TrialTicket(atr).SetCancelIfExpired());

            // 找出使用了但是未放款的券
            var todayInDetails = repayTime.ToString("yyyy-MM-dd");
            var unpaidTickets  = context.li_activity_transactions.Where(
                a =>
                a.activity_type == (int)Agp2pEnums.ActivityTransactionActivityTypeEnum.TrialTicket &&
                a.status == (int)Agp2pEnums.ActivityTransactionStatusEnum.Confirm &&
                a.details.Contains(todayInDetails))     // 查找放款日是今日
                                 .Where(a => a.transact_time == null)
                                 .ToList();

            // 添加活动备注,减去钱包待收利息,创建钱包历史
            unpaidTickets.ForEach(atr =>
            {
                atr.remarks       = "体验标收益";
                atr.transact_time = repayTime;

                var wallet              = atr.dt_users.li_wallets;
                wallet.idle_money      += atr.value;
                wallet.profiting_money -= atr.value;
                wallet.total_profit    += atr.value;
                wallet.last_update_time = repayTime;

                var his = TransactionFacade.CloneFromWallet(wallet, Agp2pEnums.WalletHistoryTypeEnum.GainConfirm);
                his.li_activity_transactions = atr;
                context.li_wallet_histories.InsertOnSubmit(his);
            });

            if (unpaidTickets.Any())
            {
                context.AppendAdminLog(DTEnums.ActionEnum.Edit.ToString(), "体验券自动放款:" + unpaidTickets.Count);
            }

            context.SubmitChanges();
        }
        public static void DoCheckDelayInvestOverTime(TimerMsg.Type timerType, bool onTime)
        {
            if (timerType != TimerMsg.Type.AutoRepayTimer)
            {
                return;
            }

            var context       = new Agp2pDataContext();
            var delayInvested = context.li_project_transactions.Where(
                ptr =>
                ptr.type == (int)Agp2pEnums.ProjectTransactionTypeEnum.Invest &&
                ptr.status == (int)Agp2pEnums.ProjectTransactionStatusEnum.Pending &&
                ptr.create_time < DateTime.Today)
                                .AsEnumerable()
                                .Where(ptr => ptr.li_projects.IsHuoqiProject())
                                .ToList();

            if (!delayInvested.Any())
            {
                return;
            }

            delayInvested.ForEach(ptr =>
            {
                var amount = TransactionFacade.QueryHuoqiBuyableClaimsAmount(context, ptr.li_projects, ptr.investor);
                if (ptr.principal < amount)
                {
                    TransactionFacade.DelayInvestSuccess(ptr.id);
                    context.AppendAdminLog("Huoqi", $"活期延期投资成功,用户 {ptr.dt_users.GetFriendlyUserName()},金额 {ptr.principal}");
                }
                else
                {
                    TransactionFacade.DelayInvestFailure(ptr.id);
                    context.AppendAdminLog("Huoqi", $"活期延期投资失败,用户 {ptr.dt_users.GetFriendlyUserName()},金额 {ptr.principal}");
                }
                context.SubmitChanges();
            });
        }
示例#6
0
        private static void DoPayBonusInterest(int projectId, DateTime projectCompleteTime)
        {
            var context = new Agp2pDataContext();

            // 找出未支付的奖励
            var projectAtrs = context.li_activity_transactions.Where(atr =>
                                                                     atr.activity_type == (byte)Agp2pEnums.ActivityTransactionActivityTypeEnum.InterestRateTicket &&
                                                                     atr.status == (byte)Agp2pEnums.ActivityTransactionStatusEnum.Confirm &&
                                                                     atr.type == (byte)Agp2pEnums.ActivityTransactionTypeEnum.Gain &&
                                                                     atr.transact_time == null &&
                                                                     (atr.details.Contains("\"ProjectId\":" + projectId + ",") || atr.details.Contains("\"ProjectId\":" + projectId + "}")))
                              .ToLookup(atr => atr.dt_users);

            // 支付奖励并减去代收金额
            projectAtrs.ForEach(userTickets =>
            {
                var wallet = userTickets.Key.li_wallets;
                userTickets.ForEach(atr =>
                {
                    //丰付获取收益
                    var msg = new HongbaoPayReqMsg(atr.user_id, atr.value);
                    MessageBus.Main.Publish(msg);
                    var msgResp = BaseRespMsg.NewInstance <HongbaoPayRespMsg>(msg.SynResult);
                    MessageBus.Main.Publish(msgResp);

                    if (msgResp.HasHandle)
                    {
                        atr.remarks       = "加息券收益";
                        atr.transact_time = projectCompleteTime;

                        wallet.profiting_money -= atr.value;
                        wallet.idle_money      += atr.value;
                        wallet.total_profit    += atr.value;
                        wallet.last_update_time = projectCompleteTime;

                        var his = TransactionFacade.CloneFromWallet(wallet, Agp2pEnums.WalletHistoryTypeEnum.GainConfirm);
                        his.li_activity_transactions = atr;
                        context.li_wallet_histories.InsertOnSubmit(his);
                    }
                });
            });

            if (projectAtrs.Any())
            {
                context.AppendAdminLog(DTEnums.ActionEnum.Edit.ToString(), "加息券自动放款用户数:" + projectAtrs.Count);
            }

            context.SubmitChanges();
        }
示例#7
0
        protected void btnBecomeTransferable_OnClick(object sender, EventArgs e)
        {
            var transferAmount = Request["__EVENTARGUMENT"];
            int claimId        = Convert.ToInt32(((LinkButton)sender).CommandArgument);
            var claim          = LqContext.li_claims.Single(c => c.id == claimId);

            var remark = string.Format("将项目【{0}】的债权 {1} 设置为可转让", claim.li_projects.title, claimId);

            LqContext.AppendAdminLog(DTEnums.ActionEnum.Edit.ToString(), remark, false);
            TransactionFacade.StaticProjectWithdraw(LqContext, claimId, 1 - Convert.ToDecimal(transferAmount) / 100);

            ShowClaimsInfo(claim.li_projects);

            JscriptMsg(remark, "");
        }
        private static void TryCompleteDelayInvest(int needTransferClaimId)
        {
            var context       = new Agp2pDataContext();
            var delayInvested = context.li_project_transactions.Where(
                ptr =>
                ptr.type == (int)Agp2pEnums.ProjectTransactionTypeEnum.Invest &&
                ptr.status == (int)Agp2pEnums.ProjectTransactionStatusEnum.Pending)
                                .AsEnumerable()
                                .Where(ptr => ptr.li_projects.IsHuoqiProject())
                                .ToList();

            if (!delayInvested.Any())
            {
                return;
            }

            // 有中间人买入过的债权才可以进行活期投资
            var agentClaimAppended = context.li_claims.Single(c => c.id == needTransferClaimId)
                                     .Children.Any(c => c.status == (int)Agp2pEnums.ClaimStatusEnum.Transferable && c.dt_users.IsAgent());

            if (!agentClaimAppended)
            {
                return;
            }

            delayInvested.ForEach(ptr =>
            {
                var amount = TransactionFacade.QueryHuoqiBuyableClaimsAmount(context, ptr.li_projects, ptr.investor);
                if (ptr.principal < amount)
                {
                    TransactionFacade.DelayInvestSuccess(ptr.id);
                    context.AppendAdminLog("Huoqi", $"活期延期投资成功,用户 {ptr.dt_users.GetFriendlyUserName()},金额 {ptr.principal}");
                    context.SubmitChanges();
                }
            });
        }
示例#9
0
        private static void DoAutoMakeLoan(TimerMsg.Type timerType, bool onTime)
        {
            if (timerType != TimerMsg.Type.AutoMakeLoanTimer)
            {
                return;
            }

            var db       = new Agp2pDataContext();
            var huoqiPro = db.li_projects.OrderByDescending(p => p.publish_time).FirstOrDefault(p => p.dt_article_category.call_index == "huoqi");

            if (huoqiPro != null)
            {
                //查询活期项目放款余额
                var reqMsg = new QueryProjectReqMsg(huoqiPro.id);
                MessageBus.Main.PublishAsync(reqMsg, ar =>
                {
                    var msgResp  = BaseRespMsg.NewInstance <QueryProjectRespMsg>(reqMsg.SynResult);
                    msgResp.Sync = true;
                    MessageBus.Main.Publish(msgResp);
                    db.AppendAdminLog("AutoMakeLoan", "查询今日放款余额为:" + msgResp.LoanAccountBalance);
                    db.SubmitChanges();
                });
            }
        }
示例#10
0
        /// <summary>
        /// 处理托管接口请求响应
        /// </summary>
        /// <param name="isSync">是否同步返回</param>
        protected void DoResponse(bool isSync = false)
        {
            Agp2pDataContext context = new Agp2pDataContext();

            try
            {
                string reqStr = ReadReqStr();
                ResponseLog = new li_pay_response_log()
                {
                    request_id       = string.IsNullOrEmpty(Request["requestId"]) ? null : Request["requestId"],
                    result           = string.IsNullOrEmpty(Request["result"]) ? "" : Request["result"],
                    status           = (int)Agp2pEnums.SumapayResponseEnum.Return,
                    response_time    = DateTime.Now,
                    response_content = reqStr
                };
                if (!string.IsNullOrEmpty(ResponseLog.request_id))
                {
                    //根据响应报文找到对应的request,生成处理消息,对应各种消息处理逻辑
                    RequestLog =
                        context.li_pay_request_log.SingleOrDefault(r => r.id == ResponseLog.request_id);
                    if (RequestLog != null)
                    {
                        //检查请求是否已经处理过
                        if (RequestLog.status != (int)Agp2pEnums.SumapayRequestEnum.Complete)
                        {
                            BaseRespMsg respMsg = null;
                            switch (RequestLog.api)
                            {
                            //个人/企业 开户/激活
                            case (int)Agp2pEnums.SumapayApiEnum.URegi:
                            case (int)Agp2pEnums.SumapayApiEnum.URegM:
                            case (int)Agp2pEnums.SumapayApiEnum.Activ:
                            case (int)Agp2pEnums.SumapayApiEnum.CRegi:
                                respMsg = new UserRegisterRespMsg(reqStr);
                                break;

                            //个人自动投标续约
                            case (int)Agp2pEnums.SumapayApiEnum.AtBid:
                                respMsg = new AutoBidSignRespMsg(reqStr);
                                break;

                            //个人自动投标取消
                            case (int)Agp2pEnums.SumapayApiEnum.ClBid:
                                respMsg = new AutoBidSignRespMsg(reqStr, true);
                                break;

                            //个人/企业 自动账户/银行还款开通
                            case (int)Agp2pEnums.SumapayApiEnum.AcReO:
                            case (int)Agp2pEnums.SumapayApiEnum.CcReO:
                            case (int)Agp2pEnums.SumapayApiEnum.AbReO:
                                respMsg = new AutoRepaySignRespMsg(reqStr);
                                break;

                            //个人/企业 自动还款取消
                            case (int)Agp2pEnums.SumapayApiEnum.ClRep:
                            case (int)Agp2pEnums.SumapayApiEnum.CancR:
                                respMsg = new AutoRepaySignRespMsg(reqStr, true);
                                break;

                            //企业/个人网银充值
                            case (int)Agp2pEnums.SumapayApiEnum.WeRec:
                            case (int)Agp2pEnums.SumapayApiEnum.CeRec:
                                respMsg = new RechargeRespMsg(reqStr);
                                break;

                            //个人一键充值
                            case (int)Agp2pEnums.SumapayApiEnum.WhRec:
                            case (int)Agp2pEnums.SumapayApiEnum.WhReM:
                                respMsg = new WithholdingRechargeRespMsg(reqStr);
                                break;

                            //个人投标/自动投标 普通/集合项目
                            case (int)Agp2pEnums.SumapayApiEnum.MaBid:
                            case (int)Agp2pEnums.SumapayApiEnum.McBid:
                            case (int)Agp2pEnums.SumapayApiEnum.MaBiM:
                            case (int)Agp2pEnums.SumapayApiEnum.McBiM:
                            case (int)Agp2pEnums.SumapayApiEnum.AmBid:
                            case (int)Agp2pEnums.SumapayApiEnum.AcBid:
                                respMsg = new BidRespMsg(reqStr);
                                break;

                            //个人撤标
                            case (int)Agp2pEnums.SumapayApiEnum.CaPro:
                            case (int)Agp2pEnums.SumapayApiEnum.CoPro:
                                respMsg = new WithDrawalRespMsg(reqStr);
                                break;

                            //流标普通项目
                            case (int)Agp2pEnums.SumapayApiEnum.RePro:
                                respMsg = new RepealProjectRespMsg(reqStr);
                                break;

                            //普通/集合项目放款
                            case (int)Agp2pEnums.SumapayApiEnum.ALoan:
                            case (int)Agp2pEnums.SumapayApiEnum.CLoan:
                                respMsg = new MakeLoanRespMsg(reqStr);
                                break;

                            //个人/企业提现
                            case (int)Agp2pEnums.SumapayApiEnum.Wdraw:
                            case (int)Agp2pEnums.SumapayApiEnum.Cdraw:
                            case (int)Agp2pEnums.SumapayApiEnum.WdraM:
                                respMsg = new WithdrawRespMsg(reqStr, isSync);
                                break;

                            //个人/企业 存管账户还款普通/集合项目
                            case (int)Agp2pEnums.SumapayApiEnum.MaRep:
                            case (int)Agp2pEnums.SumapayApiEnum.McRep:
                            case (int)Agp2pEnums.SumapayApiEnum.CaRep:
                            case (int)Agp2pEnums.SumapayApiEnum.CoRep:
                                respMsg = new RepayRespMsg(reqStr);
                                break;

                            //个人协议还款普通/集合项目
                            case (int)Agp2pEnums.SumapayApiEnum.BaRep:
                            case (int)Agp2pEnums.SumapayApiEnum.BcRep:
                                respMsg = new RepayRespMsg(reqStr, true);
                                break;

                            //个人自动还款普通/集合项目
                            case (int)Agp2pEnums.SumapayApiEnum.AcRep:
                            case (int)Agp2pEnums.SumapayApiEnum.AbRep:
                            case (int)Agp2pEnums.SumapayApiEnum.CcRep:
                            case (int)Agp2pEnums.SumapayApiEnum.CbRep:
                                respMsg = new RepayRespMsg(reqStr, false, true);
                                break;

                            //普通/集合项目本息到账
                            case (int)Agp2pEnums.SumapayApiEnum.RetPt:
                            case (int)Agp2pEnums.SumapayApiEnum.RetCo:
                                respMsg = new ReturnPrinInteRespMsg(reqStr);
                                break;

                            //债权转让
                            case (int)Agp2pEnums.SumapayApiEnum.CreAs:
                            case (int)Agp2pEnums.SumapayApiEnum.CreAM:
                                respMsg = new CreditAssignmentRespMsg(reqStr);
                                break;

                            //查询项目
                            case (int)Agp2pEnums.SumapayApiEnum.QuPro:
                                respMsg = BaseRespMsg.NewInstance <QueryProjectRespMsg>(reqStr);
                                break;

                            //银行卡解绑
                            case (int)Agp2pEnums.SumapayApiEnum.RemCa:
                                respMsg = new RemoveCardRespMsg(reqStr);
                                break;

                            //红包付款至用户
                            case (int)Agp2pEnums.SumapayApiEnum.HbPay:
                                respMsg = new HongbaoPayRespMsg(reqStr);
                                break;

                            default:
                                respMsg = new BaseRespMsg();
                                break;
                            }

                            //发送响应消息处理
                            MessageBus.Main.Publish(respMsg);
                            //更新日志信息
                            ResponseLog.user_id      = respMsg.UserIdIdentity;
                            ResponseLog.project_id   = respMsg.ProjectCode;
                            RequestLog.complete_time = DateTime.Now;
                            if (respMsg.HasHandle)
                            {
                                ResponseLog.status = (int)Agp2pEnums.SumapayResponseEnum.Complete;
                                RequestLog.status  = (int)Agp2pEnums.SumapayRequestEnum.Complete;
                            }
                            else
                            {
                                ResponseLog.status = (int)Agp2pEnums.SumapayResponseEnum.Invalid;
                                RequestLog.status  = (int)Agp2pEnums.SumapayRequestEnum.Fail;
                                //记录失败信息
                                ResponseLog.remarks += respMsg.Remarks;
                            }
                            context.li_pay_response_log.InsertOnSubmit(ResponseLog);
                        }
                    }
                    else
                    {
                        context.AppendAdminLog("SumaPayNotic", "没有找到对应的请求,RequestID:" + ResponseLog.request_id);
                    }
                }
                else
                {
                    context.AppendAdminLog("SumaPayNotic", "请求流水号为空!返回报文为:" + reqStr);
                }
            }
            catch (Exception ex)
            {
                context.AppendAdminLog("SumaPayNotic", "noticeUrl 内部错误:" + ex.Message);
            }
            //解决错误“找不到行或已修改”
            try
            {
                context.SubmitChanges(System.Data.Linq.ConflictMode.ContinueOnConflict);
            }
            catch (System.Data.Linq.ChangeConflictException ex)
            {
                //不再提交数据更新
                new Agp2pDataContext().AppendAdminLogAndSave("SumaPayNotic", "noticeUrl 找不到行或已修改:" + ex.Message);
            }
        }
示例#11
0
 public static void AppendAdminLogAndSave(this Agp2pDataContext context, string actionType, string remark, bool sysLog = true, int userId = 1, string userName = "******")
 {
     context.AppendAdminLog(actionType, remark, sysLog, userId, userName);
     context.SubmitChanges();
 }
示例#12
0
        public static void DoGainLoanerRepayment(TimerMsg.Type timerType, bool onTime)
        {
            if (timerType != TimerMsg.Type.LoanerRepayTimer)
            {
                return;
            }

            // 找出今天需要回款,并且没有收取还款的计划
            var context         = new Agp2pDataContext();
            var shouldRepayTask = context.li_repayment_tasks.Where(t =>
                                                                   t.li_projects.li_risks.li_loaners != null &&
                                                                   t.status == (int)Agp2pEnums.RepaymentStatusEnum.Unpaid &&
                                                                   t.should_repay_time.Date <= DateTime.Today)
                                  .AsEnumerable()
                                  .Where(t =>
            {
                var loaner = t.li_projects.li_risks.li_loaners;
                return(!loaner.dt_users.li_bank_transactions.Any(
                           btr =>
                           btr.type == (int)Agp2pEnums.BankTransactionTypeEnum.GainLoanerRepay &&
                           btr.status == (int)Agp2pEnums.BankTransactionStatusEnum.Confirm && btr.remarks == t.id.ToString()));
            })
                                  .ToList();

            if (!shouldRepayTask.Any())
            {
                return;
            }

            shouldRepayTask.ForEach(t =>
            {
                var project = context.li_projects.SingleOrDefault(p => p.id == t.project);
                if (project != null)
                {
                    var loaner = project.li_risks.li_loaners.dt_users;
                    try
                    {
                        if (project.IsHuoqiProject() || (project.autoRepay != null && (bool)project.autoRepay))
                        {
                            //创建自动还款托管接口请求
                            var autoRepayReqMsg = loaner.dt_user_groups.title.Equals("融资合作组") ?
                                                  new CompanyAutoRepayReqMsg(loaner.id, t.project, (t.repay_principal + t.repay_interest).ToString("f")) :
                                                  new AutoRepayReqMsg(loaner.id, t.project, (t.repay_principal + t.repay_interest).ToString("f"));
                            autoRepayReqMsg.Remarks = $"isEarly=false&repayTaskId={t.id}";
                            //发送请求
                            MessageBus.Main.PublishAsync(autoRepayReqMsg, msg =>
                            {
                                //处理请求同步返回结果
                                var repayRespMsg       = BaseRespMsg.NewInstance <RepayRespMsg>(msg.SynResult);
                                repayRespMsg.AutoRepay = true;
                                MessageBus.Main.PublishAsync(repayRespMsg);
                            });
                        }
                    }
                    catch (Exception ex)
                    {
                        context.AppendAdminLog("GainLoanerRepayment",
                                               ex.Message == "借款人的余额不足"
                                ? $"借款人 {loaner.GetFriendlyUserName()} 的余额小于还款计划需要收取的金额 {t.repay_principal + t.repay_interest}"
                                : ex.GetSimpleCrashInfo());
                    }
                }
            });
        }
示例#13
0
        public static void DoHuoqiProjectWithdraw(TimerMsg.Type timerType, bool onTime, DateTime withdrawAt)
        {
            if (timerType != TimerMsg.Type.AutoRepayTimer)
            {
                return;
            }

            var context   = new Agp2pDataContext();
            var repayTime = DateTime.Now;

            // 对 withdrawDay 的前一天的 Unpaid 债权进行回款(方便在脚本中使用)
            var checkDay = withdrawAt.Date.AddDays(-1);

            // 执行未回款债权的回款,减少项目的在投金额(必须要是今日之前的提现)
            var claims = context.li_claims.Where(
                c =>
                (c.status == (int)Agp2pEnums.ClaimStatusEnum.CompletedUnpaid ||
                 c.status == (int)Agp2pEnums.ClaimStatusEnum.TransferredUnpaid) &&
                c.Parent.createTime.Date == checkDay && !c.Children.Any()).ToList();

            if (!claims.Any())
            {
                return;
            }

            // 查询出昨日的全部提现及其是第几次的提现
            var yesterdayWithdraws = context.li_claims.Where(c =>
                                                             c.status == (int)Agp2pEnums.ClaimStatusEnum.NeedTransfer &&
                                                             c.Parent.status == (int)Agp2pEnums.ClaimStatusEnum.Nontransferable &&
                                                             c.createTime.Date == checkDay)
                                     .GroupBy(c => c.dt_users)
                                     .ToDictionary(g => g.Key, g =>
                                                   g.Zip(Utils.Infinite(), (claim, index) => new { claim, index })
                                                   .ToDictionary(e => e.claim, e => e.index));

            claims.ToLookup(c => c.li_projects_profiting).ForEach(pcs =>
            {
                var huoqiProject = pcs.Key;
                //发送托管本金到账请求成功后才执行转出逻辑
                RequestApiHandle.SendReturnPrinInte(huoqiProject.id, pcs,
                                                    () => {
                    pcs.ToLookup(c => c.dt_users).ForEach(ucs =>
                    {
                        var investor = ucs.Key;
                        var wallet   = investor.li_wallets;

                        ucs.ForEach(c =>
                        {
                            Agp2pEnums.ClaimStatusEnum newStatus;
                            if (c.status == (int)Agp2pEnums.ClaimStatusEnum.CompletedUnpaid)
                            {
                                newStatus = Agp2pEnums.ClaimStatusEnum.Completed;
                            }
                            else if (c.status == (int)Agp2pEnums.ClaimStatusEnum.TransferredUnpaid)
                            {
                                newStatus = Agp2pEnums.ClaimStatusEnum.Transferred;
                            }
                            else
                            {
                                throw new InvalidOperationException("活期项目 T+1 提款出错:未知的债权状态");
                            }

                            var newStatusChild = c.NewStatusChild(repayTime, newStatus);
                            context.li_claims.InsertOnSubmit(newStatusChild);

                            // 提现大于 3 次后每次提现都扣除手续费 0.25%
                            var userYesterdayWithdraws = yesterdayWithdraws[c.dt_users];
                            var parentClaim            = userYesterdayWithdraws.Keys.Single(c.IsChildOf);
                            var withdrawIndex          = userYesterdayWithdraws[parentClaim];
                            //TODO 手续费率需要按照配置?
                            var handlingFee = withdrawIndex <= 2 ? 0 : c.principal * 0.25m / 100;

                            var withdrawTransact = new li_project_transactions
                            {
                                principal     = c.principal - handlingFee,
                                project       = huoqiProject.id,
                                create_time   = repayTime,
                                investor      = investor.id,
                                type          = (byte)Agp2pEnums.ProjectTransactionTypeEnum.HuoqiProjectWithdraw,
                                status        = (byte)Agp2pEnums.ProjectTransactionStatusEnum.Success,
                                gainFromClaim = c.id,
                                remark        = $"活期项目【{huoqiProject.title}】债权赎回成功:债权金额 {c.principal.ToString("c")},赎回费 {handlingFee.ToString("c")}"
                            };
                            context.li_project_transactions.InsertOnSubmit(withdrawTransact);

                            wallet.idle_money      += withdrawTransact.principal;
                            wallet.investing_money -= c.principal;
                            wallet.last_update_time = repayTime;

                            var his = TransactionFacade.CloneFromWallet(wallet, Agp2pEnums.WalletHistoryTypeEnum.HuoqiProjectWithdrawSuccess);
                            his.li_project_transactions = withdrawTransact;
                            context.li_wallet_histories.InsertOnSubmit(his);
                        });
                    });
                });
            });
            context.AppendAdminLog("HuoqiWithdraw", "今日活期项目提现成功: " + claims.Sum(c => c.principal).ToString("c"));

            context.SubmitChanges();
        }
示例#14
0
        /// <summary>
        /// 发送投资成功消息
        /// </summary>
        /// <param name="projectTransactionId"></param>
        /// <param name="investTime"></param>
        private static void HandleProjectInvestMsg(int projectTransactionId, DateTime investTime)
        {
            var context = new Agp2pDataContext();

            try
            {
                //找出项目投资信息
                var investment = context.li_project_transactions.Single(p => p.id == projectTransactionId);

                //发送电子合同
                siteconfig siteConfig = ConfigLoader.loadSiteConfig();
                //增加协议号到投资记录中
                investment.agree_no = investment.li_projects.dt_article_category.call_index.ToUpper() + Utils.GetOrderNumber();
                //获得投资协议邮件内容
                var bodytxt = context.GetInvestContractContext(investment, AppDomain.CurrentDomain.BaseDirectory + "\\tools\\invest-agreement.html");
                //发送投资协议邮件
                // TODO 新手体验标 不发投资协议到邮箱
                if (!string.IsNullOrWhiteSpace(investment.dt_users.email) && !investment.li_projects.IsNewbieProject1())
                {
                    DTMail.sendMail(siteConfig.emailsmtp,
                                    siteConfig.emailusername,
                                    DESEncrypt.Decrypt(siteConfig.emailpassword),
                                    siteConfig.emailnickname,
                                    siteConfig.emailfrom,
                                    investment.dt_users.email,
                                    "安广融合投资协议", bodytxt);
                }

                // 检测用户是否接收放款的通知
                var sendNotificationSettings = context.li_notification_settings.Where(n => n.user_id == investment.investor)
                                               .Select(n => n.type).Cast <Agp2pEnums.DisabledNotificationTypeEnum>();

                if (sendNotificationSettings.Contains(Agp2pEnums.DisabledNotificationTypeEnum.InvestSuccessForUserMsg))
                {
                    return;
                }
                else
                {
                    context.SubmitChanges();
                }

                //发送投资站内信息
                var dtSmsTemplate = context.dt_sms_template.FirstOrDefault(t => t.call_index == "invest_success");
                if (dtSmsTemplate == null)
                {
                    return;
                }

                var content = dtSmsTemplate.content.Replace("{date}", investment.create_time.ToString("yyyy年MM月dd日HH时mm分"))
                              .Replace("{projectName}", investment.li_projects.title)
                              .Replace("{amount}", investment.principal.ToString("N"));

                var userMsg = new dt_user_message
                {
                    type             = 1,
                    post_user_name   = "",
                    accept_user_name = investment.dt_users.user_name,
                    title            = dtSmsTemplate.title,
                    content          = content,
                    post_time        = investTime,
                    receiver         = investment.investor
                };
                context.dt_user_message.InsertOnSubmit(userMsg);
                context.SubmitChanges();
            }
            catch (Exception ex)
            {
                context.AppendAdminLog("Invest", "发送投资成功消息时错误:" + ex.Message);
                context.SubmitChanges();
            }
        }