Esempio n. 1
0
        private static void HandleProjectRepayCompletedMsg(int projectId, DateTime projectCompleteTime)
        {
            // 找出投资记录对应的活动奖励记录
            var context = new Agp2pDataContext();

            var invitees = context.li_invitations.Where(i => i.li_project_transactions.project == projectId).Select(i => i.dt_users1).Distinct();
            var atr      = invitees.Select(i =>
                                           i.li_activity_transactions.Single(a =>
                                                                             a.activity_type == (int)Agp2pEnums.ActivityTransactionActivityTypeEnum.RefereeFirstTimeProfitBonus))
                           .ToList();  // 查出邀请人的奖励活动交易记录

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

            atr.ForEach(tr =>
            {
                tr.transact_time = projectCompleteTime;
                tr.status        = (byte)Agp2pEnums.ActivityTransactionStatusEnum.Confirm;

                var wallet              = tr.dt_users.li_wallets;
                wallet.idle_money      += tr.value;
                wallet.total_profit    += tr.value;
                wallet.last_update_time = projectCompleteTime;

                var his = TransactionFacade.CloneFromWallet(wallet, Agp2pEnums.WalletHistoryTypeEnum.GainConfirm);
                his.li_activity_transactions = tr;
                context.li_wallet_histories.InsertOnSubmit(his);
            });
            context.SubmitChanges();
        }
Esempio n. 2
0
        private static void DoCalcProfitingMoney(int projectId, DateTime makeLoanTime)
        {
            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(p =>
            {
                var wallet = p.Key.li_wallets;
                p.ForEach(atr =>
                {
                    // 满标时再计算待收益金额
                    wallet.profiting_money += atr.value;
                    wallet.last_update_time = makeLoanTime;
                    // 修改钱包历史
                    var his = TransactionFacade.CloneFromWallet(wallet, Agp2pEnums.WalletHistoryTypeEnum.Gaining);
                    his.li_activity_transactions = atr;
                    context.li_wallet_histories.InsertOnSubmit(his);
                });
            });
            if (projectAtrs.Any())
            {
                context.SubmitChanges();
            }
        }
Esempio n. 3
0
        /// <summary>
        /// 新手标第一期逻辑(停用)
        /// </summary>
        /// <param name="projectTransactionId"></param>
        public static void CheckNewbieInvest(int projectTransactionId)
        {
            var context = new Agp2pDataContext();
            var ptr     = context.li_project_transactions.Single(tr => tr.id == projectTransactionId);
            var project = ptr.li_projects;

            if (!project.IsNewbieProject1())
            {
                return;
            }

            if (project.repayment_type != (int)Agp2pEnums.ProjectRepaymentTypeEnum.DaoQi)
            {
                throw new InvalidOperationException("新手标只考虑了到期还款付息的情况");
            }

            if (project.li_repayment_tasks.Any(r => r.only_repay_to == ptr.investor))
            {
                throw new InvalidOperationException("已经创建过此投资者的回款计划");
            }

            // 创建针对单个用户的还款计划
            var finalProfitRate = 0.1m;// project.GetFinalProfitRate(ptr.create_time); // 暂时写死利率为 1/10,即投资 100 元有 10 元

            var ta = new li_repayment_tasks
            {
                project           = project.id,
                repay_interest    = Math.Round(finalProfitRate * ptr.principal, 2),
                repay_principal   = ptr.principal,
                status            = (byte)Agp2pEnums.RepaymentStatusEnum.Unpaid,
                term              = 1,
                should_repay_time = project.CalcRepayTimeByTerm(1, ptr.create_time),
                only_repay_to     = ptr.investor
            };

            context.li_repayment_tasks.InsertOnSubmit(ta);

            // 修改代收利息,添加钱包历史
            var wallet = ptr.dt_users.li_wallets;

            wallet.profiting_money += ta.repay_interest;
            wallet.last_update_time = ptr.create_time;

            var history = TransactionFacade.CloneFromWallet(wallet, Agp2pEnums.WalletHistoryTypeEnum.InvestSuccess);

            history.li_project_transactions = ptr;
            context.li_wallet_histories.InsertOnSubmit(history);

            // 如果体验标完成了,则设置为完成
            if (project.financing_amount == project.investment_amount)
            {
                project.status = (int)Agp2pEnums.ProjectStatusEnum.RepayCompleteIntime;
                project.invest_complete_time = ptr.create_time;
                project.complete_time        = ptr.create_time;
            }
            context.SubmitChanges();
        }
Esempio n. 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();
        }
Esempio n. 5
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();
        }
Esempio n. 6
0
            public void Use(Agp2pDataContext context, int projectId)
            {
                if (IsUsed())
                {
                    throw new Exception("此体验券已经使用过了");
                }
                if (IsExpired())
                {
                    throw new Exception("此体验券已经过期了");
                }

                var proj = context.li_projects.Single(p => p.id == projectId);

                if ((int)Agp2pEnums.ProjectStatusEnum.Financing != proj.status)
                {
                    throw new InvalidOperationException("项目不是发标状态,不能投资");
                }

                var ticketValue = GetTicketValue();

                // 判断投资金额的数额是否合理
                var canBeInvest = proj.financing_amount - proj.investment_amount;

                if (canBeInvest == 0)
                {
                    throw new InvalidOperationException("项目已经满标");
                }
                if (canBeInvest < ticketValue)
                {
                    throw new InvalidOperationException("体验券金额 " + ticketValue + " 超出项目可投资金额 " + canBeInvest);
                }
                if (canBeInvest != ticketValue && canBeInvest - ticketValue < 100)
                {
                    throw new InvalidOperationException("最后一次投标的最低金额为 " + canBeInvest + " 元");
                }

                var useTime = DateTime.Now;
                // 计算利息
                var rate = proj.GetFinalProfitRate(useTime);

                atr.value = Math.Round(ticketValue * rate, 2);
                // 计算放款时间
                var repayTime = proj.CalcRepayTimeByTerm(proj.CalcRealTermCount(), useTime);

                var jsonObj = (JObject)JsonConvert.DeserializeObject(atr.details);

                jsonObj["ProjectId"] = projectId;
                jsonObj["RepayTime"] = repayTime.ToString("yyyy-MM-dd HH:mm:ss");
                atr.remarks          = string.Format("[体验券]将于 {0:yyyy-MM-dd} 收益 {1:c}", repayTime, atr.value);
                atr.details          = jsonObj.ToString(Formatting.None);
                atr.status           = (int)Agp2pEnums.ActivityTransactionStatusEnum.Confirm;

                // 修改项目已投资金额
                proj.investment_amount += ticketValue;
                if (proj.investment_amount == proj.financing_amount) // 如果项目满了,设置为满标
                {
                    proj.invest_complete_time = useTime;
                    proj.status         = (int)Agp2pEnums.ProjectStatusEnum.ProjectRepaying;
                    proj.make_loan_time = useTime;
                }

                // 修改钱包,添加待收金额

                var wallet = atr.dt_users.li_wallets;

                // 满标时再计算待收益金额
                wallet.profiting_money += atr.value;
                wallet.last_update_time = useTime;

                // 修改钱包历史
                var his = TransactionFacade.CloneFromWallet(wallet, Agp2pEnums.WalletHistoryTypeEnum.Gaining);

                his.li_activity_transactions = atr;
                context.li_wallet_histories.InsertOnSubmit(his);

                context.SubmitChanges();
            }
Esempio n. 7
0
        private static void HandleUserInvestedMsg(int projectTransactionId, DateTime investTime)
        {
            var context = new Agp2pDataContext();

            var projectTransaction = context.li_project_transactions.Single(tr => tr.id == projectTransactionId);

            var unactived = context.li_activity_transactions.Where(a =>
                    a.user_id == projectTransaction.investor && a.status == (int)Agp2pEnums.ActivityTransactionStatusEnum.Acting &&
                    a.type == (int)Agp2pEnums.ActivityTransactionTypeEnum.Gain &&
                    a.activity_type == (int)Agp2pEnums.ActivityTransactionActivityTypeEnum.HongBao).ToList();
            if (!unactived.Any()) return;

            var wallet = context.li_wallets.Single(w => w.user_id == projectTransaction.investor);
            decimal investAmount = projectTransaction.principal;

            // 优先取得较大的红包,一样大的话优先满足快过期的红包
            var rps = unactived.Select(a => new HongBao(a))
                    .OrderByDescending(a => a.GetInvestUntil())
                    .ThenBy(a => a.GetDeadline())
                    .ToList();

            // 汇总未激活红包的投资金额
            investAmount += rps.Sum(rp => rp.GetInvested());
            rps.ForEach(rp => rp.SetInvested(null));

            foreach (var rp in rps)
            {
                if (rp.GetInvestUntil() <= investAmount) // 投资足够激活红包
                {
                    

                    //丰付支付
                    var msg = new HongbaoPayReqMsg(rp.atr.user_id, rp.atr.value);
                    MessageBus.Main.Publish(msg);
                    var msgResp = BaseRespMsg.NewInstance<HongbaoPayRespMsg>(msg.SynResult);
                    MessageBus.Main.Publish(msgResp);

                    if (msgResp.HasHandle)
                    {
                        investAmount -= rp.GetInvestUntil();

                        // 红包激活,发放奖金,更改状态
                        rp.Activate(investTime);
                        var curr = rp.atr;


                        wallet.idle_money += curr.value;
                        wallet.last_update_time = investTime;

                        var his = TransactionFacade.CloneFromWallet(wallet, Agp2pEnums.WalletHistoryTypeEnum.GainConfirm);
                        his.li_activity_transactions = curr;
                        context.li_wallet_histories.InsertOnSubmit(his);
                    }
                }
            }
            // 有剩余投资金额不够激活钱包的话将其记在第一个未被激活的红包
            var firstRp = rps.FirstOrDefault(rp => rp.atr.status == (int)Agp2pEnums.ActivityTransactionStatusEnum.Acting);
            if (0 < investAmount && firstRp != null)
            {
                firstRp.SetInvested(investAmount);
            }
            context.SubmitChanges();
        }
Esempio n. 8
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();
        }