Exemplo n.º 1
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();
        }
Exemplo n.º 2
0
        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)); // 广播项目融资超时的消息
            });
        }
Exemplo n.º 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();
        }
Exemplo n.º 4
0
        public static void InitDailyTimer(TimerMsg.Type timerType, string autoRepayTime)
        {
            var match = new Regex(@"^(\d{1,2}):(\d{2}):(\d{2})$").Match(autoRepayTime);

            if (match.Success)
            {
                SchaduleDailyTimer(timerType, Convert.ToInt32(match.Groups[1].Value), Convert.ToInt32(match.Groups[2].Value), Convert.ToInt32(match.Groups[3].Value));
            }
            else
            {
                throw new InvalidOperationException("不正确的日期格式:" + autoRepayTime);
            }
        }
Exemplo n.º 5
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();
        }
Exemplo n.º 6
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.InterestRateTicket &&
                                                   a.status == (int)Agp2pEnums.ActivityTransactionStatusEnum.Acting)
            .AsEnumerable()
            .ForEach(atr => new InterestRateTicket(atr).SetCancelIfExpired());

            context.SubmitChanges();
        }
Exemplo n.º 7
0
        public static void DoRepay(TimerMsg.Type timerType, bool onTime)
        {
            if (timerType != TimerMsg.Type.AutoRepayTimer)
            {
                return;
            }
            if (ConfigLoader.loadSiteConfig().enableAutoRepay == 0)
            {
                return;
            }

            var context         = new Agp2pDataContext();
            var shouldRepayTask = context.li_repayment_tasks.Where(
                t =>
                t.status == (int)Agp2pEnums.RepaymentStatusEnum.Unpaid &&
                t.should_repay_time.Date <= DateTime.Today).ToList();

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


            // 优先进行特殊项目的回款
            shouldRepayTask.OrderByDescending(t => t.li_projects.dt_article_category.sort_id).ForEach(ta =>
            {
                //TODO 特殊项目回款处理
                //if (ta.li_projects.IsNewbieProject())
                //{
                //    context.ExecuteRepaymentTask(ta.id);
                //}
                //else
                //调用托管本息到账接口,在本息到账异步响应中执行还款计划
                RequestApiHandle.SendReturnPrinInte(ta.project, (ta.repay_interest + ta.repay_principal).ToString("f"), ta.id, false, ta.li_projects.IsHuoqiProject());
            });

            context.AppendAdminLogAndSave("AutoRepay", "今日待还款项目自动还款:" + shouldRepayTask.Count);

            // 活期项目不发兑付公告
            SendRepayNotice(shouldRepayTask.Where(t => !t.li_projects.IsHuoqiProject()).ToList(), context);
        }
Exemplo n.º 8
0
        private static void DoCheckOverTimePaid(TimerMsg.Type timerType, bool onTime)
        {
            if (timerType != TimerMsg.Type.AutoRepayTimer)
            {
                return;
            }

            var db       = new Agp2pDataContext();
            var overTime =
                db.li_repayment_tasks.Where(
                    r => r.status == (int)Agp2pEnums.RepaymentStatusEnum.Unpaid && DateTime.Now > r.should_repay_time)
                .ToList();

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

            overTime.ForEach(o => o.status = (int)Agp2pEnums.RepaymentStatusEnum.OverTime);
            db.SubmitChanges();
        }
Exemplo n.º 9
0
        /// <summary>
        /// 新手标第一期自动返10元(停用)
        /// </summary>
        /// <param name="timerName"></param>
        /// <param name="onTime"></param>
        private static void HandleTimerMsg(TimerMsg.Type timerName, bool onTime)
        {
            if (timerName != TimerMsg.Type.AutoRepayTimer)
            {
                return;
            }

            var context         = new Agp2pDataContext();
            var shouldRepayTask = context.li_repayment_tasks.Where(
                t =>
                t.only_repay_to != null &&
                (t.status == (int)Agp2pEnums.RepaymentStatusEnum.Unpaid || t.status == (int)Agp2pEnums.RepaymentStatusEnum.OverTime) &&
                t.should_repay_time.Date <= DateTime.Today).ToList();

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

            shouldRepayTask.ForEach(ta => context.ExecuteRepaymentTask(ta.id));
            context.AppendAdminLogAndSave("AutoRepay", "新手体验标自动还款:" + string.Join(", ", shouldRepayTask.Select(t => t.dt_users.user_name).ToArray()));
        }
Exemplo n.º 10
0
        public static void SchaduleDailyTimer(TimerMsg.Type timerType, int hours, int minutes = 0, int seconds = 0, bool todayExecuted = false)
        {
            var dailyTimer = TimerDict.GetValueOrDefault(timerType, (DailyTimer)null);

            if (dailyTimer != null && dailyTimer.Running)
            {
                dailyTimer.Release();
            }
            dailyTimer = new DailyTimer(hours, minutes, seconds, callBackEnum =>
            {
                MessageBus.Main.Publish(new TimerMsg(timerType, onTime: callBackEnum == CallBackEnum.OnTime));
                if (callBackEnum == CallBackEnum.OnTime)
                {
                    new Agp2pDataContext().AppendAdminLogAndSave("Timer", "全局定时器执行了一次:" + timerType);
                }
            }, ex =>
            {
                new Agp2pDataContext().AppendAdminLogAndSave("Timer", "全局定时器报错:" + ex.GetSimpleCrashInfo());
                //if (Utils.IsDebugging()) throw ex;
            });
            TimerDict[timerType] = dailyTimer;
        }
        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();
            });
        }
Exemplo n.º 12
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();
                });
            }
        }
Exemplo n.º 13
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());
                    }
                }
            });
        }
Exemplo n.º 14
0
        private static void HandleTimerMessage(TimerMsg.Type timerType, bool onTime)
        {
            if (timerType != TimerMsg.Type.AutoRepayTimer)
            {
                return;
            }

            // 安广融合借款人还款提醒:您的借款项目【{project}】第 {termNumber} 期{remainDays}天后将到期,本期应还本金 {principal} 加利息 {interest} 共计 {total}。
            var context        = new Agp2pDataContext();
            var willRepayTasks =
                context.li_repayment_tasks.Where(
                    t =>
                    (t.should_repay_time.Date == DateTime.Today.AddDays(3) || t.should_repay_time.Date == DateTime.Today.AddDays(1)) &&
                    t.status == (int)Agp2pEnums.RepaymentStatusEnum.Unpaid).ToList();

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

            var smsTemplate = context.dt_sms_template.SingleOrDefault(te => te.call_index == "loaner_repay_hint")?.content;

            if (smsTemplate == null)
            {
                context.AppendAdminLogAndSave("LoanerRepayHint", "找不到还款提醒模板: loaner_repay_hint");
                smsTemplate = "您的借款项目【{project}】第 {termNumber} 期{remainDays}天后将到期,本期应还本金 {principal} 加利息 {interest} 共计 {total}。";
            }

            willRepayTasks.ForEach(task =>
            {
                var loaner = task.li_projects.li_risks.li_loaners.dt_users;
                if (string.IsNullOrEmpty(loaner.mobile))
                {
                    return;
                }

                // 判断一天内有没有发送过短信
                var alreadySend = 1 <= context.QueryEventTimesDuring(loaner.id, Agp2pEnums.EventRecordTypeEnum.LoanerRepaymentRemind, TimeSpan.FromDays(1), task.id.ToString());
                if (alreadySend)
                {
                    return;
                }

                var smsContent = smsTemplate
                                 .Replace("{remainDays}", (task.should_repay_time.Date - DateTime.Today).TotalDays.ToString("n0"))
                                 .Replace("{project}", task.li_projects.title)
                                 .Replace("{termNumber}", task.term.ToString())
                                 .Replace("{principal}", task.repay_principal.ToString("c"))
                                 .Replace("{interest}", task.repay_interest.ToString("c"))
                                 .Replace("{total}", (task.repay_principal + task.repay_interest).ToString("c"));

                try
                {
                    var errorMsg = string.Empty;
                    if (!SMSHelper.SendTemplateSms(loaner.mobile, smsContent, out errorMsg))
                    {
                        context.AppendAdminLogAndSave("LoanerRepayHint",
                                                      $"发送还款提醒失败:{errorMsg}(借款人ID:{loaner.user_name},项目名称:{task.li_projects.title})");
                    }
                    else
                    {
                        context.MarkEventOccurNotSave(loaner.id, Agp2pEnums.EventRecordTypeEnum.LoanerRepaymentRemind, DateTime.Now, task.id.ToString());
                        context.SubmitChanges();
                    }
                }
                catch (Exception ex)
                {
                    context.AppendAdminLogAndSave("LoanerRepayHint",
                                                  $"发送还款提醒失败:{ex.GetSimpleCrashInfo()}(借款人ID:{loaner.user_name},项目名称:{task.li_projects.title})");
                }
            });
        }
Exemplo n.º 15
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();
        }
Exemplo n.º 16
0
        public static void HuoqiClaimTransferToCompanyWhenNeeded(TimerMsg.Type timerType, bool onTime)
        {
            if (timerType != TimerMsg.Type.AutoRepayTimer)
            {
                return;
            }

            using (var ts = new TransactionScope())
            {
                // 将需要转让的债权由中间人购买,转手之后设置为 TransferredUnpaid
                var context      = new Agp2pDataContext();
                var companyUsers = context.dt_users.Where(u => u.dt_user_groups.title == AutoRepay.AgentGroup).ToList();
                if (!companyUsers.Any())
                {
                    throw new InvalidOperationException("请先往“中间户”的会员组添加会员");
                }

                // 接手昨日/更早的提现
                var needTransferClaims = context.li_claims.Where(
                    c =>
                    c.projectId != c.profitingProjectId && c.status == (int)Agp2pEnums.ClaimStatusEnum.NeedTransfer &&
                    !c.Children.Any() && c.createTime.Date < DateTime.Today)
                                         .ToList();

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

                //根据活期项目发送还款请求
                needTransferClaims.ToLookup(c => c.li_projects_profiting).ForEach(groupByProj =>
                {
                    //找出活期项目对应的中间人
                    var huoqiProj             = groupByProj.Key;
                    var loaner                = huoqiProj.li_risks.li_loaners.dt_users;
                    var needTransferClaimsSum = groupByProj.Sum(c => c.principal);
                    if (loaner.li_wallets.idle_money < needTransferClaimsSum)
                    {
                        throw new InvalidOperationException("警告:中间人的余额不足以接手需要转让的债权");
                    }

                    //创建自动还款托管接口请求
                    var autoRepayReqMsg = new AutoRepayReqMsg(loaner.id, huoqiProj.id, needTransferClaimsSum.ToString("f"));
                    MessageBus.Main.PublishAsync(autoRepayReqMsg, ar =>
                    {
                        //处理请求同步返回结果
                        var repayRespMsg        = BaseRespMsg.NewInstance <RepayRespMsg>(autoRepayReqMsg.SynResult);
                        repayRespMsg.HuoqiRepay = true;
                        MessageBus.Main.PublishAsync(repayRespMsg, result =>
                        {
                            if (repayRespMsg.HasHandle)
                            {
                                //托管还款完成后才接手转出的债权
                                context.RecaptureHuoqiClaim(groupByProj.ToList(), DateTime.Now);
                            }
                        });
                    });
                });


                ts.Complete();
            }
        }