public ActionResult GetAmortizationByAsset(string projectGuid, string paymentDate, int assetId) { return(ActionUtils.Json(() => { var project = new ProjectLogicModel(CurrentUserName, projectGuid); var dataset = project.DealSchedule.GetByPaymentDay(DateUtils.ParseDigitDate(paymentDate)).Dataset; var asset = dataset.Assets.Single(x => x.AssetId == assetId); if (asset.AmortizationType == AmortizationType.UserDefined) { var records = dataset.AmortizationSchedule.SelectByAsset(assetId); var viewModel = new PrepayRecordListViewModel(dataset.DatasetSchedule, records); viewModel.AsOfDateBegin = dataset.DatasetSchedule.AsOfDateBegin; viewModel.AsOfDateEnd = dataset.DatasetSchedule.AsOfDateEnd; return ActionUtils.Success(viewModel); } else if (IsEqualPmtOrEqualPrin(asset.AmortizationType)) { if (IsEqualPmtOrEqualPrin(asset.SecurityData.PaymentMethod)) { //当期的偿付类型是EqualPmt/EqualPrin //返回值为系统根据EqualPmt/EqualPrin测算出的本金 var basicAnalyticsData = NancyUtils.GetBasicAnalyticsData(project.Instance.ProjectId, null, dataset.Instance.AsOfDate); var assetCashflow = basicAnalyticsData.BasicAssetCashflow.BasicAssetCashflowItems.SelectByAsset(assetId); var viewModel = new PrepayRecordListViewModel(dataset.DatasetSchedule, assetCashflow); return ActionUtils.Success(viewModel); } else { //已经发生了提前偿付,后几期的偿付类型是EqualPmt/EqualPrin //返回值为提前偿付+系统根据EqualPmt/EqualPrin测算出的本金 var records = dataset.AmortizationSchedule.SelectByAsset(assetId); var viewModel = new PrepayRecordListViewModel(dataset.DatasetSchedule, records); var nextDatasetBasicAnalyticsData = NancyUtils.GetBasicAnalyticsData(project.Instance.ProjectId, null, dataset.DatasetSchedule.Next.AsOfDateBegin); var nextAssetCashflowItems = nextDatasetBasicAnalyticsData.BasicAssetCashflow.BasicAssetCashflowItems .SelectByAsset(assetId).Where(x => x.PaymentDate > dataset.DatasetSchedule.PaymentDate); viewModel.AddRange(nextAssetCashflowItems); return ActionUtils.Success(viewModel); } } else if (asset.AmortizationType == AmortizationType.SingleAmortization) { var records = dataset.AmortizationSchedule.SelectByAsset(assetId); var sumPrepayMoney = records.Sum(x => x.ReductionAmount); var viewModel = new PrepayRecordListViewModel(dataset.DatasetSchedule, records); viewModel.Add(assetId, asset.SecurityData.PrincipalBalance - sumPrepayMoney, project.DealSchedule.LegalMaturity); return ActionUtils.Success(viewModel); } return ActionUtils.Failure("无法识别的偿付类型,projectGuid=[" + projectGuid + "] + paymentDate=[" + paymentDate + "] + assetId=[" + assetId + "]"); })); }
public ActionResult CalculatePrepayAmortizationByAsset(string projectGuid, string paymentDate, int assetId, string prepayDate, double money, string distributionType) { return(ActionUtils.Json(() => { CommUtils.Assert(money >= 0, "提前偿付金额不能为负数"); var type = CommUtils.ParseEnum <PrepayDistrubutionType>(distributionType); CommUtils.Assert(type != PrepayDistrubutionType.Custom, "自定义模式下,无法预计算提前偿付数据。"); var project = new ProjectLogicModel(CurrentUserName, projectGuid); var dataset = project.DealSchedule.GetByPaymentDay(DateUtils.ParseDigitDate(paymentDate)).Dataset; var asset = dataset.Assets.Single(x => x.AssetId == assetId); CommUtils.Assert(DateUtils.ParseDigitDate(prepayDate) >= dataset.DatasetSchedule.AsOfDateBegin && DateUtils.ParseDigitDate(prepayDate) <= dataset.DatasetSchedule.AsOfDateEnd, "提前偿付日期必须在当期时间范围(" + dataset.DatasetSchedule.AsOfDateBegin.ToShortDateString() + "~" + dataset.DatasetSchedule.AsOfDateEnd.ToShortDateString() + ")内"); if (asset.AmortizationType == AmortizationType.UserDefined) { var amortization = dataset.AmortizationSchedule; amortization.AddPrepayment(assetId, DateUtils.ParseDigitDate(prepayDate), money, type); var viewModel = new PrepayRecordListViewModel(dataset.DatasetSchedule, amortization.SelectByAsset(assetId)); return ActionUtils.Success(viewModel); } //处理等额本金、等额本息、一次偿付类的提前偿付,需要下期模型存在 if (dataset.Next == null) { //下期模型不存在,自动生成下一期模型 CommUtils.AssertNotNull(dataset.DatasetSchedule.Next, "找不到下期模型封包日,提前偿付测算失败"); CreateDataset(project.Instance, dataset.DatasetSchedule.Next.AsOfDateBegin.ToString("yyyyMMdd")); var assetModifier = new AssetModifier(CurrentUserName); assetModifier.Load(project.Instance.ProjectId, dataset.DatasetSchedule.AsOfDateBegin); assetModifier.GenerateNextDataset(project.Instance.ProjectId); } CommUtils.AssertNotNull(dataset.Next, "无法找到下期模型数据,提前偿付测算失败"); if (IsEqualPmtOrEqualPrin(asset.AmortizationType)) { var curDatasetBasicAnalyticsData = NancyUtils.GetBasicAnalyticsData(project.Instance.ProjectId, null, dataset.DatasetSchedule.AsOfDateBegin); double curDatasetPrincipal = 0; if (IsEqualPmtOrEqualPrin(asset.SecurityData.PaymentMethod)) { //当期未发生过提前偿付,当期偿付金额是Nancy测算金额 curDatasetPrincipal = curDatasetBasicAnalyticsData.BasicAssetCashflow.BasicAssetCashflowItems .Single(x => x.AssetId == assetId && x.PaymentDate == dataset.DatasetSchedule.PaymentDate).Principal; } else { var nextDatasetAsset = dataset.Next.Assets.Single(x => x.AssetId == assetId); CommUtils.Assert(IsEqualPmtOrEqualPrin(nextDatasetAsset.AmortizationType), "第[" + dataset.Next.DatasetSchedule.PaymentDate.ToString("yyyyMMdd") + "]期偿付类型错误,提前偿付测算失败"); //当期发生过提前偿付,当期偿付金额是AmortizationSchedule中金额 var curAmortizationRecord = dataset.AmortizationSchedule.Single(x => x.ReductionDate == dataset.DatasetSchedule.PaymentDate); //当期未发生本次提前偿付的偿付本金 curDatasetPrincipal = (double)curAmortizationRecord.ReductionAmount; } var sumFutureDatasetPrincipal = curDatasetBasicAnalyticsData.BasicAssetCashflow.BasicAssetCashflowItems .SelectByAsset(assetId) .Where(x => x.PaymentDate > dataset.DatasetSchedule.PaymentDate) .Sum(x => x.Principal); var records = new List <AmortizationScheduleRecord>(); //当期的新的本金偿付值是 根据等额本金/等额本息计算出的本金值 加上提前偿付金额 records.Add(new AmortizationScheduleRecord() { AssetId = assetId, ReductionAmount = curDatasetPrincipal + money, ReductionDate = dataset.DatasetSchedule.PaymentDate }); var viewModel = new PrepayRecordListViewModel(dataset.DatasetSchedule, records); //更新下期的本金期末余额(减去提前偿付金额),重新根据等额本金/等额本息计算本金 dataset.Next.CollateralCsv.UpdateCellValue(assetId, "PrincipalBalance", (sumFutureDatasetPrincipal - money).ToString()); dataset.Next.CollateralCsv.Save(); var nextDatasetBasicAnalyticsData = NancyUtils.GetBasicAnalyticsData(project.Instance.ProjectId, null, dataset.DatasetSchedule.Next.AsOfDateBegin); var nextAssetCashflowItems = nextDatasetBasicAnalyticsData.BasicAssetCashflow.BasicAssetCashflowItems .SelectByAsset(assetId).Where(x => x.PaymentDate > dataset.DatasetSchedule.PaymentDate); viewModel.AddRange(nextAssetCashflowItems); //恢复下期的本金期末余额 dataset.Next.CollateralCsv.UpdateCellValue(assetId, "PrincipalBalance", sumFutureDatasetPrincipal.ToString()); dataset.Next.CollateralCsv.Save(); return ActionUtils.Success(viewModel); } else if (asset.AmortizationType == AmortizationType.SingleAmortization) { var nextDatasetAsset = dataset.Next.Assets.Single(x => x.AssetId == assetId); CommUtils.AssertEquals(nextDatasetAsset.SecurityData.PaymentMethod, ZEnums.EPaymentMethod.UNDEFINEDENUM, "无法识别的偿付类型,提前偿付测算失败。"); var nextAmortizationRecords = dataset.Next.AmortizationSchedule.SelectByAsset(assetId); CommUtils.AssertEquals(nextAmortizationRecords.Count, 0, "第[" + dataset.Next.DatasetSchedule.PaymentDate.ToString("yyyyMMdd") + "]期已发生提前偿付, 提前偿付测算失败"); var records = dataset.AmortizationSchedule.SelectByAsset(assetId); var viewModel = new PrepayRecordListViewModel(dataset.DatasetSchedule, records); viewModel.Add(assetId, money, DateUtils.ParseDigitDate(prepayDate)); var sumPrepayAmount = records.Sum(x => x.ReductionAmount); CommUtils.Assert(sumPrepayAmount <= asset.SecurityData.PrincipalBalance, "提前偿付金额[" + sumPrepayAmount + "]大于剩余未偿付金额[" + asset.SecurityData.PrincipalBalance + "]"); viewModel.Add(assetId, asset.SecurityData.PrincipalBalance - sumPrepayAmount, asset.SecurityData.MaturityDate); return ActionUtils.Success(viewModel); } return ActionUtils.Success("无法识别的偿付类型,projectGuid=[" + projectGuid + "] + paymentDate=[" + paymentDate + "] + assetId=[" + assetId + "]"); })); }