From 67349d59ae4f043790545778111dcf090a480e30 Mon Sep 17 00:00:00 2001 From: gongpei Date: Mon, 20 Apr 2026 17:00:38 +0800 Subject: [PATCH] =?UTF-8?q?=E6=94=AF=E6=8C=81=E6=94=B6=E7=9B=8A=E4=BA=92?= =?UTF-8?q?=E6=8D=A2=E7=9B=91=E7=AE=A1=E6=8A=A5=E9=80=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../YLErp.Core/DBModels/Consts/ConsReport.cs | 2 +- .../ReportSwapConfirmationAttService.cs | 160 ++++- .../Service/ReportSwapConfirmationService.cs | 604 +++++++++++++++++- .../Service/ReportSwapEquityPaymentService.cs | 216 ++++++- .../Service/ReportSwapTerminationService.cs | 351 +++++++++- .../Client_Rating/ClientRatingLogList.cshtml | 55 +- .../Views/SwapRate/OperationHistory.cshtml | 1 + .../client/ClientAssessmentHistoryLog.cshtml | 55 +- .../client/ClientOperationHistory.cshtml | 77 +-- .../Views/client/ClientTemplateChoose.cshtml | 2 +- .../Views/entryexit/ClientCashLogList.cshtml | 1 + .../trade/submissionFieldsHistory.cshtml | 2 +- 12 files changed, 1355 insertions(+), 171 deletions(-) diff --git a/Framework/YLErp.Core/DBModels/Consts/ConsReport.cs b/Framework/YLErp.Core/DBModels/Consts/ConsReport.cs index 9152f16e..154f7ee7 100644 --- a/Framework/YLErp.Core/DBModels/Consts/ConsReport.cs +++ b/Framework/YLErp.Core/DBModels/Consts/ConsReport.cs @@ -150,7 +150,7 @@ namespace YLErp.DBModels.Consts ///// ///// 系统数据 ///// - //System = 1, + System = 1, /// /// Excel模板 diff --git a/YLErpDAL/Modules/SuperviseReportModule/SAC/Service/ReportSwapConfirmationAttService.cs b/YLErpDAL/Modules/SuperviseReportModule/SAC/Service/ReportSwapConfirmationAttService.cs index 2e1e8b6c..ad07719e 100644 --- a/YLErpDAL/Modules/SuperviseReportModule/SAC/Service/ReportSwapConfirmationAttService.cs +++ b/YLErpDAL/Modules/SuperviseReportModule/SAC/Service/ReportSwapConfirmationAttService.cs @@ -46,13 +46,165 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service { fileList = new List(); var model = new BodyModel(); + var cacheKey = $"{BusiDataType}"; SACReportNotesCache = base.InitReportNotes(ReportType); SACReportNotesCache_confirmation = base.InitReportNotes(SuperviseReportTypeEnum.SAC_SwapConfirmation); var dataList = new List(); - //if (_reqInfo.DataSource.HasFlag(SAC_ReportDataSourceEnum.Template)) - //{ - dataList = GetSwapConfirmationAttModel(ref fileList); - //} + if ((PS.Config.ErpElement.SAC_ReportDataSource & SAC_ReportDataSourceEnum.System) == SAC_ReportDataSourceEnum.System) + { + var nextDate = _reqInfo.ReportDate.AddDays(1); + var nextDataDate = _reqInfo.DataDate.AddDays(1); + using (var db = new YLContext()) + { + var codeList = ReportStatus.GetCacheInfo(cacheKey); + var query = (from t in db.trade + join tr in db.trade_contract_r + on t.id equals tr.TradeId + + join td in db.trade_contract_document + on t.ContractCode equals td.Code + + where + (_operationType == OptFlagsEnum.A && t.TradeDate >= _reqInfo.DataDate && + t.TradeDate < nextDataDate) //新增时使用交易日期判断)//补正和废止时使用操作日期判断 + && (_operationType == OptFlagsEnum.D || (t.ValidState != "InValid") + && t.TradeType == "收益互换") + select new + { + t.id, + tradeContractRValid = tr.IsValid, + tradeValid = t.ValidState != "InValid", + td.Paths, + td.ValueDate, + t.ClientId, + t.TradeDate, + TradeType = t.StructureType ?? t.TradeType, + t.OptionType, + tr.ContractCode, + }).OrderBy(O => O.id).ToArray().Where(O => !codeList.Contains(O.id + "")).ToArray(); + + List ids = query.Select(O => O.id).ToList(); + List delIds = new List(); + if (_operationType == OptFlagsEnum.D) + { + delIds = DbContext.TradeAuditLog.Where(O => ids.Contains(O.TradeId) && O.OptDate >= _reqInfo.ReportDate && O.OptDate < nextDate && O.OptType == "删除交易").Select(O => O.TradeId).ToList(); + } + Dictionary> metaDic = DbContext.TradeMeta.Where(O => ids.Contains(O.TradeId)).AsEnumerable().GroupBy(O => O.TradeId).ToDictionary(K => K.Key, V => V.ToDictionary(K1 => K1.MetaKey, V1 => V1.MetaValue)); + Dictionary reportDescDic = DbContext.AppConfig.Where(O => O.PGroup == ConsAppConfig.ReportDescSwap).ToDictionary(K => K.PName, V => V.PValue); + foreach (var item in query) + { + var cacheValue = item.id.ToString(); + if (ReportStatus.CheckCacheInfo(cacheKey, cacheValue)) + { + continue; + } + //如果存在重复数据,则始终用较新的数据 + ConfirmationAttModel info = new ConfirmationAttModel(); + + info.ConfirmationNo = item.ContractCode; + var confirmationNote = base.GetReportNotes(SuperviseReportTypeEnum.SAC_SwapConfirmation, $"_{info.ConfirmationNo.Replace("_", "-")}_").FirstOrDefault(); + var currentCodes = ReportStatus.GetCacheInfo(DataFlagsEnum.A1005.ToString());//取出这一次报送交易要素的交易编号 + if (!currentCodes.Contains(item.id.ToString()) && (confirmationNote == null || !confirmationNote.ReportResponse)) + { + continue;//跳过交易要素还没报送的确认书附件; + } + SACReportNotes note = base.GetReportNotes(formatInfoTag(info)).FirstOrDefault(); + if (note == null && _operationType == OptFlagsEnum.A) + { + info.OperationType = OptFlagsEnum.A; + note = new SACReportNotes() + { + IsValid = true, + }; + } + else + { + if (note == null) + { + continue; + } + switch (_operationType) + { + case OptFlagsEnum.A: + continue;//新增数据已报送,跳过 + case OptFlagsEnum.U: + if (!note.changeStatus) + { + continue;//交易没有被修改过,跳过 + } + info.OperationType = OptFlagsEnum.U; + note.IsValid = true; + break; + case OptFlagsEnum.D: + if (!delIds.Contains(item.id)) + { + continue;//交易没有被删除,跳过 + } + info.OperationType = OptFlagsEnum.D; + note.IsValid = false; + break; + case OptFlagsEnum.NONE: + default: + throw new ServiceException("未知操作类型"); + } + } + if (info.OperationType != _operationType) + { + continue; + } + if (info.OperationType != OptFlagsEnum.D && (!item.tradeValid || !item.tradeContractRValid)) + {//非废止报送中,应跳过所有存在无效数据的数据 + continue; + } + if (metaDic.ContainsKey(item.id)) + { + var metaInfo = metaDic[item.id]; + var tradingPlace = metaInfo.ContainsKey(ConsTradeMetaKey.TradingPlace) ? TradingPlaceMap[metaInfo[ConsTradeMetaKey.TradingPlace]] : ""; + if (tradingPlace == "1")//跳过交易场所为报价系统的交易; + { + continue; + } + } + if (info.OperationType != OptFlagsEnum.A) + { + info.BizID = note.BizId;//确认书编号; + } + + + string path = item.Paths; + if (!path.StartsWith("\\") || path.StartsWith("/")) + { + path = "\\" + path; + } + var absolutePath = OtcAppContext.MapPath(path); + absolutePath = Path.ChangeExtension(absolutePath, "pdf"); + info.ConfirmationFilesTuple = new List() { new ConfirmationFilesTupleModel() { ConfirmationFiles = Path.GetFileName(absolutePath) } }; + info.ExceID = base.formatExceID(); + if (!ReportStatus.CheckFileLength(absolutePath)) + { + break; + } + fileList.Add(absolutePath); + ReportStatus.AddCacheInfo(cacheKey, cacheValue); + dataList.Add(info); + note.id = 0; + note.InfoCache = $"{{\"DueDate\":\"{item.ValueDate?.ToString("yyyy-MM-dd")}\",\"Tag\":\"{info.ConfirmationNo}\",\"Source\":\"System\"}}"; + note.ExceId = info.ExceID; + note.CreateTime = DateTime.Now; + note.FileTag = FileTag; + note.ReportType = ReportType; + note.ReportDate = _reqInfo.ReportDate; + note.InfoTag = formatInfoTag(info, true); + note.OptTime = note.CreateTime; + note.RetCode = ""; + note.RetMsg = ""; + note.ReportResponse = false; + note.BizId = ""; + note.changeStatus = false; + noteList.Add(note); + } + } + } var subsystemDataList = loadSubsystemDataSource(fileList, AddSubsystemNote); if (subsystemDataList != null && subsystemDataList.Count > 0) { diff --git a/YLErpDAL/Modules/SuperviseReportModule/SAC/Service/ReportSwapConfirmationService.cs b/YLErpDAL/Modules/SuperviseReportModule/SAC/Service/ReportSwapConfirmationService.cs index f8108ec6..fa2fb978 100644 --- a/YLErpDAL/Modules/SuperviseReportModule/SAC/Service/ReportSwapConfirmationService.cs +++ b/YLErpDAL/Modules/SuperviseReportModule/SAC/Service/ReportSwapConfirmationService.cs @@ -1,6 +1,9 @@ using BaseOUDAL; +using MathNet.Numerics; +using MoreLinq.Extensions; using Qdp.Foundation.Implementations; using System.Data; +using System.Text.Json; using YieldChain.Helpers; using YLErp.BLL; using YLErp.DBModels.Consts; @@ -27,15 +30,12 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service protected override DataFlagsEnum BusiDataType => DataFlagsEnum.A1005; private List _validOperationType = null; + public override List ValidOperationType { get { - _validOperationType ??= new List() { - OptFlagsEnum.A, - OptFlagsEnum.U, - OptFlagsEnum.D, - }; + _validOperationType ??= new List() { OptFlagsEnum.A, OptFlagsEnum.U, OptFlagsEnum.D, }; return _validOperationType; } } @@ -49,12 +49,427 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service { fileList = new List(); var model = new BodyModel(); + var cacheKey = $"{BusiDataType}"; SACReportNotesCache = base.InitReportNotes(ReportType); var dataList = new List(); - //if (_reqInfo.DataSource.HasFlag(SAC_ReportDataSourceEnum.Template)) - //{ - dataList = GetSwapConfirmationModel(ref fileList); - //} + if (_reqInfo.DataSource.HasFlag(SAC_ReportDataSourceEnum.Template)) + { + dataList = GetSwapConfirmationModel(ref fileList); + } + + if ((PS.Config.ErpElement.SAC_ReportDataSource & SAC_ReportDataSourceEnum.System) == + SAC_ReportDataSourceEnum.System) + { + // 获取所有的交易确认事件 + + var queryDate = _reqInfo.ReportDate; + using (var db = new YLContext()) + { + + var confirmEventList = (from a in db.swap_event + where a.EventType == 9 && a.OptTime >= queryDate.Date && + a.OptTime < queryDate.Date.AddDays(1) + select new + { + a.id, + swapTradeId = a.SwapTradeId, + a.ValueDate, + eventType = a.EventType, + eventData = a.EventData, + invalid = a.Invalid, + backId = a.BackId, + optTime = a.OptTime + }).OrderBy(O => O.optTime).ToList(); + + var swapTradeIds = confirmEventList.Select(O => O.swapTradeId); + if (swapTradeIds == null || swapTradeIds.Count() == 0) + { + noData = true; + return null; + } + + var codeList = ReportStatus.GetCacheInfo(cacheKey); + var query = (from t in db.trade + join tr in db.trade_contract_r + on t.id equals tr.TradeId + join sp in db.swap_position.Where(O => !O.Invalid && !O.IsInitial) on t.id equals sp.SwapTradeId + where swapTradeIds.Contains(t.id) && + (tr.Type == "交易确认书" && tr.IsValid) + select new + { + t.id, + sp.PosiNotionalValue, + sp.PositionType, + t.ClientId, + t.TradeDate, + t.ExerciseDate, + t.SettlementDate, + t.ExerciseMode, + t.BuySell, + TradeType = t.StructureType ?? t.TradeType, + t.OptionType, + t.OriginalStockEqvNotional, + t.IsMoneynessOption, + t.SpotPrice, + t.Strike, + t.MarginTemplateName, + t.MarginType, + t.InitialMargin, + t.UnderlyingCode, + t.AnnualizeFactor, + tr.ContractCode, + sp.InterestMode, + sp.InterestRateDefault, + sp.FloatRateUnderlyingCode, + sp.InterestDirection, + sp.InterestSwapInterval, + t.OpponentRole, + sp.InterestPrincipalFix, + sp.PosiDirection + }).ToList(); + + var group = query.GroupBy(O => O.ContractCode).ToDictionary(K => K.Key, V => V.ToList()); + + List ids = group.Values.SelectMany(O => O.Select(x => x.id)).Distinct().ToList(); + + Dictionary> metaDic = DbContext.TradeMeta + .Where(O => ids.Contains(O.TradeId)).AsEnumerable().GroupBy(O => O.TradeId) + .ToDictionary(K => K.Key, V => V.ToDictionary(K1 => K1.MetaKey, V1 => V1.MetaValue)); + foreach (var item in group) + { + var confirmationNo = item.Key; + if (ReportStatus.CheckCacheInfo(cacheKey, confirmationNo)) + { + continue; + } + + //如果存在重复数据,则始终用较新的数据 + SwapConfirmationModel info = new SwapConfirmationModel(); + + info.ConfirmationNo = confirmationNo; + SACReportNotes note = base.GetReportNotes(ReportType, formatInfoTag(info)).FirstOrDefault(); + if (note == null && _operationType == OptFlagsEnum.A) + { + info.OperationType = OptFlagsEnum.A; + note = new SACReportNotes() { IsValid = true, }; + } + else + { + if (note == null) + { + continue; + } + + switch (_operationType) + { + case OptFlagsEnum.A: + continue; //新增数据已报送,跳过 + case OptFlagsEnum.U: + if (!note.changeStatus) + { + continue; //交易没有被修改过,跳过 + } + + info.OperationType = OptFlagsEnum.U; + note.IsValid = true; + break; + case OptFlagsEnum.D: + // 如果有删除事件,报废止 + info.OperationType = OptFlagsEnum.D; + note.IsValid = false; + break; + case OptFlagsEnum.NONE: + default: + throw new ServiceException("未知操作类型"); + } + } + + if (info.OperationType != _operationType) + { + continue; + } + var first = item.Value.First(); + if (metaDic.ContainsKey(first.id)) + { + var metaInfo = metaDic[first.id]; + info.MasterAgrmtNo = metaInfo.ContainsKey(ConsTradeMetaKey.MainProtocolCode) + ? metaInfo[ConsTradeMetaKey.MainProtocolCode] + : ""; + info.SupAgrmtNo = metaInfo.ContainsKey(ConsTradeMetaKey.SupProtocolCode) + ? metaInfo[ConsTradeMetaKey.SupProtocolCode] + : ""; + info.ClearingAgency = metaInfo.ContainsKey(ConsTradeMetaKey.ClearingAgency) + ? ClearingAgencyMap[metaInfo[ConsTradeMetaKey.ClearingAgency]] + : ""; + info.TradingPlace = metaInfo.ContainsKey(ConsTradeMetaKey.TradingPlace) + ? TradingPlaceMap[metaInfo[ConsTradeMetaKey.TradingPlace]] + : ""; + if (info.TradingPlace == "1") //跳过交易场所为报价系统的交易; + { + continue; + } + } + + if (info.OperationType != OptFlagsEnum.A) + { + info.ConfirmationID = note.BizId; //确认书编号; + } + + info.ConfirmationType = ReportTypeMap[info.OperationType == OptFlagsEnum.A ? "首次" : "变更"]; + info.FillParty = FillPartyMap["甲方"]; + + #region 费用端支付 + + List costPaymentTupleDtos = new List(); + item.Value.ForEach(O => + { + // 说明是浮动腿,获取多空方向,肯定都是一致的,不然不可能是同一个交易编号,一直循环修改也没问题 + + if (O.PosiDirection > 0) + { + switch (O.PositionType) + { + case 1: + info.SwapType = "0"; + break; + case 2: + info.SwapType = "1"; + break; + case 3: + info.SwapType = "2"; + break; + } + } + else + { + if (O.InterestDirection > 0) + { + var costPaymentTupleDto = new CostPaymentTupleDto(); + // 计算初始保证金 + if (O.InterestMode == 5 || O.InterestMode == 6) + { + costPaymentTupleDto.InterestPrincipalFix = O.InterestPrincipalFix; + } + else + { + // 生成费用端支付 + costPaymentTupleDto.InterestRateDefault = O.InterestRateDefault; + costPaymentTupleDto.FloatRateUnderlyingCode = O.FloatRateUnderlyingCode; + costPaymentTupleDto.InterestDirection = O.InterestDirection; + costPaymentTupleDto.PaymentFreq = GetPaymentFreq(O.InterestSwapInterval); + } + + costPaymentTupleDtos.Add(costPaymentTupleDto); + } + } + }); + + List paymentMethodModels = new List(); + costPaymentTupleDtos.ForEach(cpt => + { + var paymentMethod = new PaymentMethodModel(); + paymentMethodModels.Add(paymentMethod); + paymentMethod.ConfirmationNo = confirmationNo; + paymentMethod.PaymentFreq = cpt.PaymentFreq; + paymentMethod.ReferenceofFloatingInterestRate = cpt.FloatRateUnderlyingCode; + if (cpt.FloatRateUnderlyingCode == null || cpt.FloatRateUnderlyingCode.Equals("") || + cpt.FloatRateUnderlyingCode.Equals("--")) + { + paymentMethod.PaymentMethod = "3"; + } + else + { + paymentMethod.PaymentMethod = "2"; + } + + if (cpt.InterestDirection == 1) + { + // 收取 + if ("乙方".Equals(first.OpponentRole)) + { + paymentMethod.Payer = "1"; + } + else + { + paymentMethod.Payer = "0"; + } + } + else + { + if ("乙方".Equals(first.OpponentRole)) + { + paymentMethod.Payer = "0"; + } + else + { + paymentMethod.Payer = "1"; + } + } + + if (cpt.FloatRateUnderlyingCode == null || cpt.FloatRateUnderlyingCode.Equals("") || + cpt.FloatRateUnderlyingCode.Equals("--")) + { + if (cpt.InterestRateDefault == 0) + { + paymentMethod.FixedInterestRate = "0"; + } + + { + paymentMethod.FixedInterestRate = + cpt.InterestRateDefault.RoundToMultiple(100).ToString(); + } + } + + if (cpt.FloatRateUnderlyingCode != null) + { + paymentMethod.FloatInterestRate = "99"; + } + + if (cpt.FloatRateUnderlyingCode != null && !cpt.FloatRateUnderlyingCode.Equals("") && + cpt.InterestRateDefault != null) + { + paymentMethod.BasePoint = cpt.InterestRateDefault.RoundToMultiple(100).ToString(); + } + }); + + info.CostPaymentTuple = paymentMethodModels ; + + + #endregion + + var variety = DataCacheProvider.GetVariety(first.UnderlyingCode); + + info.StartDate = first.TradeDate?.ToString("yyyy-MM-dd"); + info.DueDate = first.ExerciseDate?.ToString("yyyy-MM-dd"); + info.SettlementDate = (first.SettlementDate ?? first.ExerciseDate)?.ToString("yyyy-MM-dd"); + info.Currency = ((int)CurrencyEnum.CNY).ToString(); + info.NotinalPrincipleAmt = (first.OriginalStockEqvNotional)?.ToString("0.00"); + info.UndrlygAssetType = string.IsNullOrWhiteSpace(variety.MainCategoryDesc) + ? UndrlygAssetTypeMap["其他"] + : UndrlygAssetTypeMap[variety.MainCategoryDesc]; + var count = item.Value.Select(O => O.UnderlyingCode).Distinct().Count(); + info.PtyAUndrlygAssetNo = UndrlygAssetNoMap[count == 1 ? "0" : "1"]; + + #region 履约担保 + + var files = db.trade_file.Where(O => O.TradeId == first.id).ToArray(); + info.PerformanceGuaranteeType = first.MarginType == MarginTypeEnum.NONE + ? PerformanceGuaranteeMap["无履约担保"] + : PerformanceGuaranteeMap["部分担保"]; + if (first.MarginType != MarginTypeEnum.NONE) + { + info.PerformanceCollProvider = PerformanceCollProviderMap["乙方"]; + info.PartyUseColl = + ConsReport.BoolMap[ + valuedateBLL.SystemDate.PartyUseColl || + PS.Config.Company == Configuration.CompanyEnum.东莞 + ? "是" + : "否"]; //todo:读取用户输入 + info.CollInstruction = valuedateBLL.SystemDate.CollInstruction; //todo:读取用户输入 + info.CalculateCollInterest = BoolMap["否"]; + if (first.InterestPrincipalFix == 0) + { + info.PerformanceCollInitialRatio = "0"; + } + else + { + if (first.OriginalStockEqvNotional != 0) + { + info.PerformanceCollInitialRatio = (first.InterestPrincipalFix * 100 / + first.OriginalStockEqvNotional?.ToDecimal()) + .ToString(); + } + } + + info.PerformanceCollAddtlRatio = "100"; + info.PerformanceCollOffsetRatio = "100"; + info.MaintainGuaranteeRatio = info.PerformanceCollInitialRatio; + + var file_PerformanceGuarante = + files.FirstOrDefault(O => O.Path.ToLower().EndsWith("履约保证书.pdf")); + info.PerformanceGuaranteeAtt = Path.GetFileName(file_PerformanceGuarante?.Path); + info.PerformanceGuaranteeRemark = file_PerformanceGuarante?.Description; + info.PerformanceCollTuple = new List(); + info.PerformanceCollTuple.Add(new SwapPerformanceGuaranteeAttModel() + { + PerformanceCollType = PerformanceCollTypeMap["现金"], + PerformanceCollRange = /*item.MarginType == MarginTypeEnum.DEFAULT ? PerformanceCollRangeMap["本笔交易对应主协议框架下的所有交易"] :*/ + PerformanceCollRangeMap["仅本笔交易"] + }); + if (!ReportStatus.CheckFileLength(file_PerformanceGuarante?.Path)) + { + break; + } + + fileList.Add(file_PerformanceGuarante?.Path); + } + else + { + info.PerformanceCollInitialRatio = "0"; + info.MaintainGuaranteeRatio = "0"; + } + + #endregion + + var file_ComplianceOpinion = files.FirstOrDefault(O => O.Path.ToLower().EndsWith("合规意见书.pdf")); + if (!string.IsNullOrWhiteSpace(file_ComplianceOpinion?.Path)) + { + string fileName = Path.GetFileName(file_ComplianceOpinion?.Path); + info.ComplianceOpinion = fileName; + if (!ReportStatus.CheckFileLength(file_ComplianceOpinion?.Path)) + { + break; + } + + fileList.Add(file_ComplianceOpinion?.Path); + } + + var client = DataCacheProvider.GetClientDataSource().GetData(first.ClientId); + info.PtyAPrOfitCalculationInfo = "详见交易确认书及定义性文件"; + + if (client.ClientType == "产品") + { + if (info.FillParty == FillPartyMap["甲方"]) + { + info.PtyBPdctName = client.Name ?? ""; + info.PytBPdctCode = client.Number ?? ""; + } + else + { + info.PtyAPdctName = client.Name ?? ""; + info.PytAPdctCode = client.Number ?? ""; + } + } + + info.ExceID = base.formatExceID(); + + // 把要报的交易确认书缓存起来 + ReportStatus.AddCacheInfo(cacheKey, confirmationNo); + foreach (var swapTradeId in swapTradeIds) + { + ReportStatus.AddCacheInfo($"{cacheKey}_{info.ConfirmationNo}_{_operationType}", swapTradeId.ToString()); + } + dataList.Add(info); + note.id = 0; + note.InfoCache = + $"{{\"NotinalPrincipleAmt\":\"{info.NotinalPrincipleAmt}\",\"DueDate\":\"{info.DueDate}\",\"Tag\":\"{info.ConfirmationNo}\",\"Source\":\"System\"}}"; + note.ExceId = info.ExceID; + note.CreateTime = DateTime.Now; + note.FileTag = FileTag; + note.ReportType = ReportType; + note.ReportDate = _reqInfo.ReportDate; + note.InfoTag = formatInfoTag(info, true); + note.OptTime = note.CreateTime; + note.RetCode = ""; + note.RetMsg = ""; + note.ReportResponse = false; + note.BizId = ""; + note.changeStatus = false; + noteList.Add(note); + } + } + } + var subsystemDataList = loadSubsystemDataSource(fileList, AddSubsystemNote); if (subsystemDataList != null && subsystemDataList.Count > 0) { @@ -69,12 +484,14 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service public bool AddSubsystemNote(SwapConfirmationModel model, List fileList, string tag) { - var note = base.GetReportNotes(ReportType, formatInfoTag(model, true), dataSource: SACReportNotesCache).FirstOrDefault();//参数true要加,要不A和D会查到同一条记录,在D时候,就会和A相同的数据 + var note = base.GetReportNotes(ReportType, formatInfoTag(model, true), dataSource: SACReportNotesCache) + .FirstOrDefault(); //参数true要加,要不A和D会查到同一条记录,在D时候,就会和A相同的数据 if (note == null) { note = new SACReportNotes() { - InfoCache = $"{{\"NotinalPrincipleAmt\":\"{model.NotinalPrincipleAmt}\",\"DueDate\":\"{model.DueDate}\",\"Tag\":\"{model.ConfirmationNo}\",\"Source\":\"Subsystem\",\"SubFileTag\":\"{tag}\",\"ExceID\":\"{model.ExceID}\"}}", + InfoCache = + $"{{\"NotinalPrincipleAmt\":\"{model.NotinalPrincipleAmt}\",\"DueDate\":\"{model.DueDate}\",\"Tag\":\"{model.ConfirmationNo}\",\"Source\":\"Subsystem\",\"SubFileTag\":\"{tag}\",\"ExceID\":\"{model.ExceID}\"}}", IsValid = true, }; } @@ -83,10 +500,11 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service switch (model.OperationType) { case OptFlagsEnum.A: - return false;//新增数据已报送,跳过 + return false; //新增数据已报送,跳过 case OptFlagsEnum.U: //多次U的时候,每次用最新的tag来赋值SubFileTag - note.InfoCache = $"{{\"NotinalPrincipleAmt\":\"{model.NotinalPrincipleAmt}\",\"DueDate\":\"{model.DueDate}\",\"Tag\":\"{model.ConfirmationNo}\",\"Source\":\"Subsystem\",\"SubFileTag\":\"{tag}\",\"ExceID\":\"{model.ExceID}\"}}"; + note.InfoCache = + $"{{\"NotinalPrincipleAmt\":\"{model.NotinalPrincipleAmt}\",\"DueDate\":\"{model.DueDate}\",\"Tag\":\"{model.ConfirmationNo}\",\"Source\":\"Subsystem\",\"SubFileTag\":\"{tag}\",\"ExceID\":\"{model.ExceID}\"}}"; note.IsValid = true; break; case OptFlagsEnum.D: @@ -106,7 +524,6 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service if (!string.IsNullOrWhiteSpace(model.ComplianceOpinion)) { - fileList.Add(model.ComplianceOpinion); } @@ -127,6 +544,73 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service noteList.Add(note); return true; } + + /// + /// 根据利息互换区间判断支付频率 + /// + /// JSON字符串,包含ObservationIntervalDto列表 + /// "0":期初支付, "1":期末支付, "2":多次支付 + private string GetPaymentFreq(string interestSwapInterval) + { + if (string.IsNullOrWhiteSpace(interestSwapInterval)) + { + return "1"; // 默认期末支付 + } + + List list = null; + try + { + list = JsonSerializer.Deserialize>(interestSwapInterval); + } + catch (JsonException ex) + { + throw new ServiceException("观察日列表json解析异常"); + } + + if (list == null || list.Count == 0) + { + return "1"; // 默认期末支付 + } + + int count = 0; + // tempDict的key:(是/否),value:出现的位置 + Dictionary tempDict = new Dictionary(); + + for (int i = 0; i < list.Count; i++) + { + ObservationIntervalDto item = list[i]; + if (item.Settlement == 1) + { + count++; + } + tempDict[item.Settlement] = i; + } + + if (count != 0) + { + // 1.如果是有多个"是"就是多次支付 + return "2"; + } + else + { + // 则证明只有一个是,判断是的位置,如果是首个,则证明是期初支付,否则期末支付(如果一个是都没有默认是期末支付) + if (tempDict.TryGetValue(1, out int index)) + { + if (index == 0) // 注意:C#索引从0开始,Java代码中判断的是1(可能是从1开始的索引) + { + return "0"; // 期初支付 + } + else + { + return "1"; // 期末支付 + } + } + else + { + return "1"; // 默认期末支付 + } + } + } private List GetSwapConfirmationModel(ref List fileList) { @@ -143,6 +627,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service //第一列空白说明数据结束了; break; } + var optType = OptFlagsEnum.NONE; switch (dt.Rows[i][3]?.ToString()) { @@ -162,6 +647,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service optType = OptFlagsEnum.D; break; } + if (optType != _operationType) { continue; @@ -186,6 +672,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service { model.Currency = ((int)currency).ToString(); } + model.NotinalPrincipleAmt = GetDataSetValue(dt, i, 10); model.ClearingAgency = ConsReport.ClearingAgencyMap[GetDataSetValue(dt, i, 11)]; model.TradingPlace = ConsReport.TradingPlaceMap[GetDataSetValue(dt, i, 12)]; @@ -225,17 +712,17 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service { continue; } + if (ReportStatus.CheckCacheInfo(CacheKey, cacheValue)) { continue; } - var note = base.GetReportNotes(ReportType, formatInfoTag(model), dataSource: SACReportNotesCache).FirstOrDefault(); + + var note = base.GetReportNotes(ReportType, formatInfoTag(model), dataSource: SACReportNotesCache) + .FirstOrDefault(); if (note == null && _operationType == OptFlagsEnum.A) { - note = new SACReportNotes() - { - IsValid = true, - }; + note = new SACReportNotes() { IsValid = true, }; } else { @@ -243,10 +730,11 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service { continue; } + switch (_operationType) { case OptFlagsEnum.A: - continue;//新增数据已报送,跳过 + continue; //新增数据已报送,跳过 case OptFlagsEnum.U: note.IsValid = true; break; @@ -257,23 +745,32 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service default: throw new ServiceException("未知操作类型"); } - var reportCacheDic = JsonHelper.ToObject>(note.InfoCache) ?? new Dictionary(); + + var reportCacheDic = JsonHelper.ToObject>(note.InfoCache) ?? + new Dictionary(); if (_operationType == OptFlagsEnum.U) { - if (reportCacheDic.ContainsKey("DueDate") && !reportCacheDic["DueDate"].StartsWith(model.DueDate) && !model.DueDate.StartsWith(reportCacheDic["DueDate"])) + if (reportCacheDic.ContainsKey("DueDate") && + !reportCacheDic["DueDate"].StartsWith(model.DueDate) && + !model.DueDate.StartsWith(reportCacheDic["DueDate"])) { throw new ServiceException("补正时,如果该交易还有存续期记录,到期日字段不能修改"); } - if (reportCacheDic.ContainsKey("NotinalPrincipleAmt") && reportCacheDic["NotinalPrincipleAmt"] != model.NotinalPrincipleAmt && reportCacheDic["NotinalPrincipleAmt"] != notinalPrincipleAmt.ToString("0")) + + if (reportCacheDic.ContainsKey("NotinalPrincipleAmt") && + reportCacheDic["NotinalPrincipleAmt"] != model.NotinalPrincipleAmt && + reportCacheDic["NotinalPrincipleAmt"] != notinalPrincipleAmt.ToString("0")) { throw new ServiceException("补正时,如果该交易还有存续期记录,名义本金额(人民币)字段不能修改"); } } } + if (model.OperationType != OptFlagsEnum.A) { - model.ConfirmationID = note.BizId;//确认书编号; + model.ConfirmationID = note.BizId; //确认书编号; } + if (!string.IsNullOrWhiteSpace(model.PerformanceGuaranteeAtt)) { path = Path.Combine(sourcePath, model.PerformanceGuaranteeAtt); @@ -281,8 +778,10 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service { break; } + fileList.Add(path); } + if (!string.IsNullOrWhiteSpace(model.ComplianceOpinion)) { path = Path.Combine(sourcePath, model.ComplianceOpinion); @@ -290,13 +789,16 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service { break; } + fileList.Add(path); } + model.ExceID = base.formatExceID(SACReportNotesCache); result.Add(model); ReportStatus.AddCacheInfo(CacheKey, cacheValue); note.id = 0; - note.InfoCache = $"{{\"NotinalPrincipleAmt\":\"{model.NotinalPrincipleAmt}\",\"DueDate\":\"{model.DueDate}\",\"Tag\":\"{model.ConfirmationNo}\",\"Source\":\"Template\"}}"; + note.InfoCache = + $"{{\"NotinalPrincipleAmt\":\"{model.NotinalPrincipleAmt}\",\"DueDate\":\"{model.DueDate}\",\"Tag\":\"{model.ConfirmationNo}\",\"Source\":\"Template\"}}"; note.ExceId = model.ExceID; note.CreateTime = DateTime.Now; note.FileTag = FileTag; @@ -312,6 +814,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service noteList.Add(note); } } + return result; } @@ -328,6 +831,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service //第一列空白说明数据结束了; break; } + if (dt.Rows[i][0]?.ToString().Trim() != confirmationNo) { continue; @@ -349,6 +853,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service result.Add(model); } } + return result; } @@ -365,6 +870,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service //第一列空白说明数据结束了; break; } + if (dt.Rows[i][0]?.ToString().Trim() != confirmationNo) { continue; @@ -381,9 +887,10 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service result.Add(model); } } + return result; } - + private string formatInfoTag(SwapConfirmationModel model, bool suffixType = false) { var result = $"{BusiDataType.ToString()}_{model.ConfirmationNo.Replace("_", "-")}_成交_"; @@ -391,6 +898,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service { result = $"{result}{_operationType}"; } + return result; } @@ -401,6 +909,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service { throw new ServiceException($"InfoTag信息不匹配:{infoTag}"); } + originalCode = arr[1]; arr[1] = newCode.Replace("_", "-"); return string.Join("_", arr); @@ -439,14 +948,12 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service }); if (listItem.Count > 0) { - var temp = new SacInfo("CostPaymentTuple", j) - { - SubMaps = new List(listItem) - }; + var temp = new SacInfo("CostPaymentTuple", j) { SubMaps = new List(listItem) }; listRoot.Add(temp); } } } + if (item.PerformanceCollTuple != null) { for (var j = 0; j < item.PerformanceCollTuple.Count; j++) @@ -467,17 +974,18 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service } } } + if (listRoot.Count > 0) { var errMsg = new SacInfo("SwapConfirmation", i) { - FieldValue = item.ConfirmationNo, - SubMaps = new List(listRoot) + FieldValue = item.ConfirmationNo, SubMaps = new List(listRoot) }; result.Add(errMsg); } } } + checkStatus = result.Count > 0; return result; } @@ -494,14 +1002,42 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service catch (Exception e) { LogFactory.GetLogger().Error(e); - }; + } + ; } + for (var i = 0; i < noteList.Count; i++) { base.SaveReportNotes(noteList[i]); } + return true; } } -} + + // 费用端支付,data transform object + class CostPaymentTupleDto + { + public decimal InterestRateDefault { get; set; } + public decimal InterestPrincipalFix { get; set; } + public string FloatRateUnderlyingCode { get; set; } + public string PaymentFreq { get; set; } + public int InterestDirection { get; set; } + } + + /// + /// 观察日区间DTO + /// + public class ObservationIntervalDto + { + /// + /// 结算标识:0-否,1-是 + /// + public int Settlement { get; set; } + + // 根据实际JSON结构添加其他属性 + // public DateTime? StartDate { get; set; } + // public DateTime? EndDate { get; set; } + } +} \ No newline at end of file diff --git a/YLErpDAL/Modules/SuperviseReportModule/SAC/Service/ReportSwapEquityPaymentService.cs b/YLErpDAL/Modules/SuperviseReportModule/SAC/Service/ReportSwapEquityPaymentService.cs index 9fc566b8..67a23731 100644 --- a/YLErpDAL/Modules/SuperviseReportModule/SAC/Service/ReportSwapEquityPaymentService.cs +++ b/YLErpDAL/Modules/SuperviseReportModule/SAC/Service/ReportSwapEquityPaymentService.cs @@ -1,9 +1,8 @@ +using MathNet.Numerics; +using System.Linq; using MoreLinq; using Qdp.Foundation.Implementations; -using System.Collections.ObjectModel; -using System.Data; using YLErp.BLL; -using YLErp.Commons; using YLErp.DBModels.Consts; using YLErp.DBModels.Enums; using YLErp.Modules.SuperviseReportModule.SAC.Common; @@ -47,13 +46,216 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service { fileList = new List(); var model = new BodyModel(); + var cacheKey = $"{BusiDataType}"; SACReportNotesCache = base.InitReportNotes(ReportType); var dataList = new List(); + if (_reqInfo.DataSource.HasFlag(SAC_ReportDataSourceEnum.Template)) + { + dataList = GetSwapEquityPaymentModel(); + } - //if (_reqInfo.DataSource.HasFlag(SAC_ReportDataSourceEnum.Template)) - //{ - dataList = GetSwapEquityPaymentModel(); - //} + if ((PS.Config.ErpElement.SAC_ReportDataSource & SAC_ReportDataSourceEnum.System) == SAC_ReportDataSourceEnum.System) + { + // 当前生成的交易确认书编号 + var confirmationNos = ReportStatus.GetCacheInfo(DataFlagsEnum.A1005.ToString());//取出这一次报送交易要素的交易编号 + foreach (var confirmationNo in confirmationNos) + { + var info = new SwapEquityPaymentModel(); + var tradeIds = ReportStatus.GetCacheInfo(DataFlagsEnum.A1005.ToString() + "_" + confirmationNo + "_" + _operationType).Select(x => int.Parse(x)).ToList(); + info.OperationType = _operationType; + info.ConfirmationNo = confirmationNo; + SACReportNotes note = base.GetReportNotes(ReportType, formatInfoTag(info)).FirstOrDefault(); + if (note == null && _operationType == OptFlagsEnum.A) + { + info.OperationType = OptFlagsEnum.A; + note = new SACReportNotes() { IsValid = true, }; + } + else + { + if (note == null) + { + continue; + } + + switch (_operationType) + { + case OptFlagsEnum.A: + continue; //新增数据已报送,跳过 + case OptFlagsEnum.U: + if (!note.changeStatus) + { + continue; //交易没有被修改过,跳过 + } + + info.OperationType = OptFlagsEnum.U; + note.IsValid = true; + break; + case OptFlagsEnum.D: + // 如果有删除事件,报废止 + info.OperationType = OptFlagsEnum.D; + note.IsValid = false; + break; + case OptFlagsEnum.NONE: + default: + throw new ServiceException("未知操作类型"); + } + } + + + var swapEquityPaymentTupleModels = new List(); + + #region 权益端支付明细 + + using (var db = new YLContext()) + { + // 查询 swap flow event + var query = (from sfe in db.swap_flow_event + join t in db.trade on sfe.SwapTradeId equals t.id + where tradeIds.Contains(sfe.SwapTradeId) && sfe.DataState == 100 && (sfe.UnderlyingCode != null && sfe.UnderlyingCode != "") + select new + { + sfe.SwapTradeId, + sfe.PositionType, + sfe.PayDirection, + sfe.TradingAmountAvg, + sfe.Quantity, + sfe.TradingAmount, + sfe.InterestFee, + sfe.InterestClosePnL, + sfe.PositionQty, + sfe.UnderlyingCode, + sfe.EventType, + sfe.ContractSize, + t.StructureType, + t.OpponentRole + }).ToList(); + + var positionTypes = query.Select(O => O.PositionType).Distinct().ToList(); + + foreach (var item in query) + { + var underlyingManager = DataCacheProvider.GetUnderlyingDataSource().GetData(item.UnderlyingCode); + var variety = DataCacheProvider.GetVarietyDataSource().GetData(underlyingManager.UnderlyingTypeId); + var sept = new SwapEquityPaymentTupleModel(); + sept.ConfirmationNo = confirmationNo; + sept.OpenandClosingDate = _reqInfo.ReportDate.ToString(); + sept.UndrlygAssetCode = item.UnderlyingCode; + sept.UndrlygAssetName = underlyingManager.UnderlyingName; + sept.UndrlygAssetTradgPlc = variety.TradingMarket; + if (positionTypes.Contains(1) && positionTypes.Contains(2)) + { + // 多空组合 + sept.PaymentMethod = "4"; + } + else if (positionTypes.Contains(1)) + { + sept.PaymentMethod = "0"; + } + else if (positionTypes.Contains(2)) + { + sept.PaymentMethod = "1"; + } + + if (item.PayDirection == 1) + { + if (item.OpponentRole.Equals("乙方")) + { + sept.Payer = "1"; + } + else + { + sept.Payer = "0"; + } + } + else + { + if (item.OpponentRole.Equals("乙方")) + { + sept.Payer = "0"; + } + else + { + sept.Payer = "1"; + } + } + + if (item.ContractSize != null) + { + sept.ContractMultiplier = item.ContractSize.ToString(); + } + + sept.PaymentFreq = "1"; + sept.UndrlygAssetPrice = item.TradingAmountAvg.RoundToMultiple(100.0m).ToString(); + if (item.EventType == 1) + { + if (item.PositionType == 1) + { + sept.UndrlygAssetPosition = "0"; + } + else + { + sept.UndrlygAssetPosition = "1"; + } + } else if (item.EventType == 2) + { + if (item.PositionType == 1) + { + sept.UndrlygAssetPosition = "2"; + } + else + { + sept.UndrlygAssetPosition = "3"; + } + } + sept.UndrlygAssetAmt = item.Quantity.ToString(); + sept.LNotinalPrincipleAmt = item.Quantity.ToString(); + if (item.PositionType == 1) + { + sept.LNotinalPrincipleAmt = item.TradingAmount.ToString(); + } + + if (item.PositionType == 2) + { + sept.SNotinalPrincipleAmt = (-item.TradingAmount).ToString(); + } + + if (!string.IsNullOrWhiteSpace(underlyingManager.UnderlyingInstrumentType)) + { + sept.UndrlygAssetDtldType = "6"; + } + else + { + sept.UndrlygAssetDtldType = "99"; + } + swapEquityPaymentTupleModels.Add(sept); + } + } + + #endregion + + info.SwapEquityPaymentTuple = swapEquityPaymentTupleModels; + info.ExceID = base.formatExceID(); + dataList.Add(info); + note.id = 0; + note.ExceId = info.ExceID; + note.CreateTime = DateTime.Now; + note.FileTag = FileTag; + note.ReportType = ReportType; + note.ReportDate = _reqInfo.ReportDate; + note.InfoTag = formatInfoTag(info, true); + note.OptTime = note.CreateTime; + note.InfoCache = ""; + note.RetCode = ""; + note.RetMsg = ""; + note.ReportResponse = false; + note.DataId = ""; + note.BizId = ""; + note.changeStatus = false; + noteList.Add(note); + } + } + + var subsystemDataList = loadSubsystemDataSource(fileList, AddSubsystemNote); if (subsystemDataList != null && subsystemDataList.Count > 0) { diff --git a/YLErpDAL/Modules/SuperviseReportModule/SAC/Service/ReportSwapTerminationService.cs b/YLErpDAL/Modules/SuperviseReportModule/SAC/Service/ReportSwapTerminationService.cs index fe9fe4bf..79cd5034 100644 --- a/YLErpDAL/Modules/SuperviseReportModule/SAC/Service/ReportSwapTerminationService.cs +++ b/YLErpDAL/Modules/SuperviseReportModule/SAC/Service/ReportSwapTerminationService.cs @@ -31,15 +31,12 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service protected override DataFlagsEnum BusiDataType => DataFlagsEnum.A1006; private List? _validOperationType = null; + public override List ValidOperationType { get { - _validOperationType ??= new List() { - OptFlagsEnum.A, - OptFlagsEnum.U, - OptFlagsEnum.D, - }; + _validOperationType ??= new List() { OptFlagsEnum.A, OptFlagsEnum.U, OptFlagsEnum.D, }; return _validOperationType; } } @@ -57,10 +54,24 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service SACReportNotesCache = base.InitReportNotes(ReportType); SACReportNotesCache_confirmation = base.InitReportNotes(SuperviseReportTypeEnum.SAC_OptionConfirmation); var dataList = new List(); - //if (_reqInfo.DataSource.HasFlag(SAC_ReportDataSourceEnum.Template)) - //{ - dataList = GetSwapDurationManagementModel(ref fileList); - //} + if (_reqInfo.DataSource.HasFlag(SAC_ReportDataSourceEnum.Template)) + { + dataList = GetSwapDurationManagementModel(ref fileList); + } + + if ((PS.Config.ErpElement.SAC_ReportDataSource & SAC_ReportDataSourceEnum.System) == + SAC_ReportDataSourceEnum.System) + { + var cacheKey = $"{BusiDataType}"; + var nextDate = _reqInfo.ReportDate.AddDays(1); + using (var db = new YLContext()) + { + dataList.AddRange(GetOptionTerminationSettlementFromDb(db, cacheKey, nextDate)); + } + + dataList = GetSwapDurationManagementModel(ref fileList); + } + var subsystemDataList = loadSubsystemDataSource(fileList, AddSubsystemNote); if (subsystemDataList != null && subsystemDataList.Count > 0) { @@ -72,9 +83,251 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service return model; } + private List GetOptionTerminationSettlementFromDb(YLContext db, string cacheKey, + DateTime nextDate) + { + // 所有的交易了结事件 + var unwindEventList = (from a in db.swap_event + join b in (from sfe in db.swap_flow_event + group sfe by new { sfe.EventId, sfe.UnwindDate } + into g + select new { EventId = g.Key.EventId, UnwindDate = g.Key.UnwindDate }) + on a.id equals b.EventId into leftJoin + from b in leftJoin.DefaultIfEmpty() + where (a.EventType == 2) + && ((a.EventType == 2 && b.UnwindDate == _reqInfo.DataDate) + || (a.EventType != 2 && a.OptTime >= _reqInfo.DataDate.Date && + a.OptTime < _reqInfo.DataDate.Date.AddDays(1))) + select new + { + a.id, + swapTradeId = a.SwapTradeId, + valueDate = a.EventType == 2 ? b.UnwindDate : + (a.EventType == 5 || a.EventType == 12) ? a.OptTime.Date : + a.ValueDate, + eventType = a.EventType, + eventData = a.EventData, + invalid = a.Invalid, + backId = a.BackId, + optTime = a.OptTime + }).OrderBy(O => O.optTime).ToList(); + + var tradeIds = unwindEventList.Select(O => O.swapTradeId).Distinct().ToList(); + + List dataList = new List(); + // 查找交易事件 + var query = (from ue in unwindEventList + join t in db.trade on ue.swapTradeId equals t.id + join cico in db.ClientCashInCashOut.Where(O => O.Action == "系统操作-平仓费") on t.id equals cico.TradeId + join tr in db.trade_contract_r.Where(O => O.Type == "交易确认书") + on t.id equals tr.TradeId + join es in db.eod_swap.Where(O => O.ValueDate == _reqInfo.DataDate) + on t.id equals es.SwapTradeId + join esp in db.eod_swap_position.Where(O => + O.ValueDate == _reqInfo.DataDate && !O.Invalid && O.PositionType > 0) + on t.id equals esp.SwapTradeId + join te in db.trade_Report on t.id equals te.TradeId + where tradeIds.Contains(t.id) && (t.TradeType == "收益互换" && tr.IsValid) + select new + { + tradeValid = t.ValueStatus != "InValid", + tradeContractRValid = tr.IsValid, + t.id, + ue.valueDate, + t.ClientId, + t.TradeDate, + t.ExerciseDate, + t.SettlementDate, + t.ExerciseMode, + t.BuySell, + TradeType = t.StructureType ?? t.TradeType, + t.OptionType, + t.OriginalStockEqvNotional, + t.StockEqvNotionalReal, + t.IsMoneynessOption, + t.SpotPrice, + t.Strike, + t.MarginTemplateName, + t.MarginType, + t.InitialMargin, + t.UnderlyingCode, + t.AnnualizeFactor, + t.OriginalNotional, + tr.ContractCode, + t.QuoteCurrency, + t.SettlementCurrency, + es.NotionalValue, + es.NotionalValueLong, + es.NotionalValueShort, + es.PostionMarginGain, + es.PostionMarginLoss, + esp.PositionType, + esp.PosiNotionalValue, + esp.PosiQuantity, + esp.PosiGrossPrice, + cico.Money + }).ToArray().GroupBy(O => new { O.valueDate, O.ContractCode }) + .ToDictionary(K => K.Key, V => V.ToList()); + + + List ids = query.Values.SelectMany(O => O.Select(x => x.id)).Distinct().ToList(); + Dictionary> metaDic = DbContext.TradeMeta + .Where(O => ids.Contains(O.TradeId)).AsEnumerable().GroupBy(O => O.TradeId).ToDictionary(K => K.Key, + V => V.ToDictionary(K1 => K1.MetaKey, V1 => V1.MetaValue)); + foreach (var item in query.ToArray()) + { + // 交易确认书编号 + var confirmationNo = item.Key.ContractCode; + var value = item.Value.First(); + + if (metaDic.ContainsKey(value.id)) + { + var metaInfo = metaDic[value.id]; + if (metaInfo.ContainsKey(ConsTradeMetaKey.TradingPlace) && + TradingPlaceMap[metaInfo[ConsTradeMetaKey.TradingPlace]] == "1") //跳过交易场所为报价系统的交易; + { + continue; + } + } + + var info = new SwapDurationManagementModel(); + + //info.TradeId = item.Key.id.ToString(); + info.DurationEventNO = "0000"; + info.DurationOperationDate = value.valueDate?.ToString("yyyy-MM-dd"); + info.ConfirmationNo = confirmationNo; + List notes = + base.GetReportNotes(ReportType, $"_{info.ConfirmationNo.Replace("_", "-")}_", true); + var note = notes.FirstOrDefault(O => + O.IsValid && O.InfoTag.Contains(formatInfoTag(info)) && + O.InfoCache.Contains(info.DurationOperationDate)); + + if (info.OperationType != _operationType) + { + continue; + } + + switch (info.OperationType) + { + case OptFlagsEnum.A: + note = new SACReportNotes() { IsValid = true, }; + break; + case OptFlagsEnum.U: + note.IsValid = true; + break; + case OptFlagsEnum.D: + note.IsValid = false; + break; + } + + if (info.OperationType != OptFlagsEnum.A) + { + info.BizID = note.BizId; + } + + info.DurationOperationType = OperationTypeMap["终止"]; + var positionTypeList = item.Value.Select(o => o.PositionType).ToList(); + if (positionTypeList.Contains(1) && positionTypeList.Contains(2)) + { + info.SwapType = "3"; + } + else if (positionTypeList.Contains(1)) + { + info.SwapType = "1"; + } + else if (positionTypeList.Contains(2)) + { + info.SwapType = "2"; + } + + + //info.TerminationAmount = currentStockEqvNotional.ToString("0.00"); + info.Balance = item.Value.Sum(O => O.PosiNotionalValue).ToString(); + // 本次支付金额 + info.AmountPaidThisTime = item.Value.Sum(O => O.Money).ToString(); + var clientBalanceDailies = (from t in db.ClientBalanceDaily + where t.ClientId == value.ClientId && t.BalanceDate == value.valueDate + select new { t.ToDayRemainFund, t.TotalNominal, t.RoundedDailyPnl }); + if (clientBalanceDailies != null) + { + var first = clientBalanceDailies.First(); + if (first.TotalNominal != 0) + { + var marginRate = (first.ToDayRemainFund + first.RoundedDailyPnl) * 100 / first.TotalNominal; + if (marginRate > 100) + { + info.MarginRatio = "100"; + } + else + { + info.MarginRatio = marginRate?.ToString("0.00"); + } + } + } + + #region 持仓明细 + + if (double.TryParse(info.Balance, out var temp) && temp > 0) + { + var currentPosition = new CurrentPositionDetailModel(); + currentPosition.UndrlygAssetCode = value.UnderlyingCode; + var codeInfo = DataCacheProvider.GetUnderlyingDataSource().GetData(value.UnderlyingCode); + currentPosition.UndrlygAssetTradgPlc = + string.IsNullOrWhiteSpace(codeInfo.MarketName) ? "其他" : codeInfo.MarketName; + + if (SwapUndrlygAssetDtldTypeMap.TryGetValue( + ConsGlobal.InstrumentType.GetDesc(codeInfo.UnderlyingInstrumentType), + out var AssetDtldType)) + { + currentPosition.UndrlygAssetDtldType = AssetDtldType; + } + else + { + currentPosition.UndrlygAssetDtldType = UndrlygAssetDtldTypeMap["其他标的"]; + } + + currentPosition.UndrlygAssetName = codeInfo.UnderlyingName; + currentPosition.InvestorPosition = info.SwapType; + currentPosition.UndrlygAssetAmt = value.PosiQuantity.ToString("0"); + currentPosition.ContractMultiplier = codeInfo.ContractSize.ToString("0"); + currentPosition.UndrlygAssetPrice = value.PosiGrossPrice.ToString("0.##"); + currentPosition.NotinalPrincipleAmt = value.PosiNotionalValue.ToString("0.##"); + info.CurrentPositionDetails = new List() { currentPosition }; + } + + #endregion + + info.ExceID = base.formatExceID(); + ReportStatus.AddCacheInfo(cacheKey, value.id.ToString()); + ReportStatus.AddCacheInfo($"{cacheKey}_{info.ConfirmationNo}", ""); + dataList.Add(info); + note.id = 0; + note.ExceId = info.ExceID; + note.InfoCache = + $"{{\"Tag\":\"{info.ConfirmationNo}\",\"ValueDate\":\"{info.DurationOperationDate}\",\"DurationEventNO\":\"{info.DurationEventNO}\",\"Source\":\"System\"}}"; + note.CreateTime = DateTime.Now; + note.FileTag = FileTag; + note.ReportType = ReportType; + note.ReportDate = _reqInfo.ReportDate; + note.InfoTag = formatInfoTag(info, true); + note.OptTime = note.CreateTime; + note.RetCode = ""; + note.RetMsg = ""; + note.ReportResponse = false; + note.BizId = ""; + note.DataId = ""; + note.changeStatus = false; + noteList.Add(note); + } + + return dataList; + } + public bool AddSubsystemNote(SwapDurationManagementModel model, List fileList, string tag) { - SACReportNotes note = base.GetReportNotes(ReportType, formatInfoTag(model, true), dataSource: SACReportNotesCache).FirstOrDefault();//参数true要加,要不A和D会查到同一条记录,在D时候,就会和A相同的数据 + SACReportNotes note = base + .GetReportNotes(ReportType, formatInfoTag(model, true), dataSource: SACReportNotesCache) + .FirstOrDefault(); //参数true要加,要不A和D会查到同一条记录,在D时候,就会和A相同的数据 var isExtensionTime = model.DurationOperationType == ConsReport.SwapOperationTypeMap["展期"]; var date = DateTime.MinValue; if (isExtensionTime) @@ -85,20 +338,25 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service { DateTime.TryParse(model.DurationOperationDate, out date); } + if (note == null) { if (isExtensionTime) { var oldDateStr = ""; - var oldData = base.GetReportNotes(SuperviseReportTypeEnum.SAC_OptionConfirmation, $"A1005_{model.ConfirmationNo.Replace("_", "-")}_成交_A", dataSource: SACReportNotesCache_confirmation).FirstOrDefault(); + var oldData = base.GetReportNotes(SuperviseReportTypeEnum.SAC_OptionConfirmation, + $"A1005_{model.ConfirmationNo.Replace("_", "-")}_成交_A", + dataSource: SACReportNotesCache_confirmation).FirstOrDefault(); oldDateStr = Regex.Match(oldData?.InfoCache ?? "", "(?<=DueDate\":\")[^\"]+(?=\")").Value; if (DateTime.TryParse(oldDateStr, out var oldDate)) { oldDateStr = $",\"OldMaturityDate\":\"{oldDate.ToString("yyyy-MM-dd")}\""; } + note = new SACReportNotes() { - InfoCache = $"{{\"Tag\":\"{model.ConfirmationNo}\"{oldDateStr},\"NewMaturityDate\":\"{date.ToString("yyyy-MM-dd")}\",\"DurationEventNO\":\"{model.DurationEventNO}\",\"Source\":\"Subsystem\",\"SubFileTag\":\"{tag}\",\"ExceID\":\"{model.ExceID}\"}}", + InfoCache = + $"{{\"Tag\":\"{model.ConfirmationNo}\"{oldDateStr},\"NewMaturityDate\":\"{date.ToString("yyyy-MM-dd")}\",\"DurationEventNO\":\"{model.DurationEventNO}\",\"Source\":\"Subsystem\",\"SubFileTag\":\"{tag}\",\"ExceID\":\"{model.ExceID}\"}}", IsValid = true, }; } @@ -106,34 +364,40 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service { note = new SACReportNotes() { - InfoCache = $"{{\"Tag\":\"{model.ConfirmationNo}\",\"ValueDate\":\"{date.ToString("yyyy-MM-dd")}\",\"DurationEventNO\":\"{model.DurationEventNO}\",\"Source\":\"Subsystem\",\"SubFileTag\":\"{tag}\",\"ExceID\":\"{model.ExceID}\"}}", + InfoCache = + $"{{\"Tag\":\"{model.ConfirmationNo}\",\"ValueDate\":\"{date.ToString("yyyy-MM-dd")}\",\"DurationEventNO\":\"{model.DurationEventNO}\",\"Source\":\"Subsystem\",\"SubFileTag\":\"{tag}\",\"ExceID\":\"{model.ExceID}\"}}", IsValid = true, }; } - } else { switch (_operationType) { case OptFlagsEnum.A: - return false;//新增数据已报送,跳过 + return false; //新增数据已报送,跳过 case OptFlagsEnum.U: if (isExtensionTime) { var oldDateStr = ""; - var oldData = base.GetReportNotes(SuperviseReportTypeEnum.SAC_OptionConfirmation, $"A1005_{model.ConfirmationNo.Replace("_", "-")}_成交_A", dataSource: SACReportNotesCache_confirmation).FirstOrDefault(); + var oldData = base.GetReportNotes(SuperviseReportTypeEnum.SAC_OptionConfirmation, + $"A1005_{model.ConfirmationNo.Replace("_", "-")}_成交_A", + dataSource: SACReportNotesCache_confirmation).FirstOrDefault(); oldDateStr = Regex.Match(oldData?.InfoCache ?? "", "(?<=DueDate\":\")[^\"]+(?=\")").Value; if (DateTime.TryParse(oldDateStr, out var oldDate)) { oldDateStr = $",\"OldMaturityDate\":\"{oldDate.ToString("yyyy-MM-dd")}\""; } - note.InfoCache = $"{{\"Tag\":\"{model.ConfirmationNo}\"{oldDateStr},\"NewMaturityDate\":\"{date.ToString("yyyy-MM-dd")}\",\"DurationEventNO\":\"{model.DurationEventNO}\",\"Source\":\"Subsystem\",\"SubFileTag\":\"{tag}\",\"ExceID\":\"{model.ExceID}\"}}"; + + note.InfoCache = + $"{{\"Tag\":\"{model.ConfirmationNo}\"{oldDateStr},\"NewMaturityDate\":\"{date.ToString("yyyy-MM-dd")}\",\"DurationEventNO\":\"{model.DurationEventNO}\",\"Source\":\"Subsystem\",\"SubFileTag\":\"{tag}\",\"ExceID\":\"{model.ExceID}\"}}"; } else { - note.InfoCache = $"{{\"Tag\":\"{model.ConfirmationNo}\",\"ValueDate\":\"{date.ToString("yyyy-MM-dd")}\",\"DurationEventNO\":\"{model.DurationEventNO}\",\"Source\":\"Subsystem\",\"SubFileTag\":\"{tag}\",\"ExceID\":\"{model.ExceID}\"}}"; + note.InfoCache = + $"{{\"Tag\":\"{model.ConfirmationNo}\",\"ValueDate\":\"{date.ToString("yyyy-MM-dd")}\",\"DurationEventNO\":\"{model.DurationEventNO}\",\"Source\":\"Subsystem\",\"SubFileTag\":\"{tag}\",\"ExceID\":\"{model.ExceID}\"}}"; } + note.IsValid = true; break; case OptFlagsEnum.D: @@ -184,6 +448,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service //第一列空白说明数据结束了; break; } + var optType = OptFlagsEnum.NONE; switch (dt.Rows[i][1]?.ToString()) { @@ -203,6 +468,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service optType = OptFlagsEnum.D; break; } + if (optType != _operationType) { continue; @@ -238,11 +504,13 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service { DateTime.TryParse(model.DurationOperationDate, out date); } + var cacheValue = $"{model.ConfirmationNo}_{model.DurationEventNO}_"; if (ReportStatus.CheckCacheInfo(CacheKey, cacheValue)) { continue; } + if (!string.IsNullOrWhiteSpace(model.SwapDurationManagementAtt)) { var path = Path.Combine(sourcePath, model.SwapDurationManagementAtt); @@ -250,26 +518,35 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service { break; } + fileList.Add(path); } + var extensionTimeInfo = isExtensionTime ? "-" : ""; - List notes = base.GetReportNotes(ReportType, $"_{model.ConfirmationNo.Replace("_", "-")}_", true, SACReportNotesCache); + List notes = base.GetReportNotes(ReportType, + $"_{model.ConfirmationNo.Replace("_", "-")}_", true, SACReportNotesCache); //永远查找现有成功报送了结的新增记录,而不是修改; - var note = notes.LastOrDefault(O => O.IsValid && O.InfoTag.Contains(formatInfoTag(model, extensionTimeInfo: extensionTimeInfo)) && O.InfoCache.Contains(date.ToString("yyyy-MM-dd"))); + var note = notes.LastOrDefault(O => + O.IsValid && O.InfoTag.Contains(formatInfoTag(model, extensionTimeInfo: extensionTimeInfo)) && + O.InfoCache.Contains(date.ToString("yyyy-MM-dd"))); if (note == null && _operationType == OptFlagsEnum.A) { if (isExtensionTime) { var oldDateStr = ""; - var oldData = base.GetReportNotes(SuperviseReportTypeEnum.SAC_OptionConfirmation, $"A1005_{model.ConfirmationNo.Replace("_", "-")}_成交_A", dataSource: SACReportNotesCache_confirmation).FirstOrDefault(); + var oldData = base.GetReportNotes(SuperviseReportTypeEnum.SAC_OptionConfirmation, + $"A1005_{model.ConfirmationNo.Replace("_", "-")}_成交_A", + dataSource: SACReportNotesCache_confirmation).FirstOrDefault(); oldDateStr = Regex.Match(oldData?.InfoCache ?? "", "(?<=DueDate\":\")[^\"]+(?=\")").Value; if (DateTime.TryParse(oldDateStr, out var oldDate)) { oldDateStr = $",\"OldMaturityDate\":\"{oldDate.ToString("yyyy-MM-dd")}\""; } + note = new SACReportNotes() { - InfoCache = $"{{\"Tag\":\"{model.ConfirmationNo}\"{oldDateStr},\"NewMaturityDate\":\"{date.ToString("yyyy-MM-dd")}\",\"DurationEventNO\":\"{model.DurationEventNO}\",\"Source\":\"Template\"}}", + InfoCache = + $"{{\"Tag\":\"{model.ConfirmationNo}\"{oldDateStr},\"NewMaturityDate\":\"{date.ToString("yyyy-MM-dd")}\",\"DurationEventNO\":\"{model.DurationEventNO}\",\"Source\":\"Template\"}}", IsValid = true, }; } @@ -277,7 +554,8 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service { note = new SACReportNotes() { - InfoCache = $"{{\"Tag\":\"{model.ConfirmationNo}\",\"ValueDate\":\"{date.ToString("yyyy-MM-dd")}\",\"DurationEventNO\":\"{model.DurationEventNO}\",\"Source\":\"Template\"}}", + InfoCache = + $"{{\"Tag\":\"{model.ConfirmationNo}\",\"ValueDate\":\"{date.ToString("yyyy-MM-dd")}\",\"DurationEventNO\":\"{model.DurationEventNO}\",\"Source\":\"Template\"}}", IsValid = true, }; } @@ -288,10 +566,11 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service { continue; } + switch (_operationType) { case OptFlagsEnum.A: - continue;//新增数据已报送,跳过 + continue; //新增数据已报送,跳过 case OptFlagsEnum.U: note.IsValid = true; break; @@ -302,7 +581,9 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service default: throw new ServiceException("未知操作类型"); } - note.InfoCache = Regex.Replace(note.InfoCache, "(?<=NewMaturityDate\":\")[^\"]+ (?= \")", date.ToString("yyyy-MM-dd")); + + note.InfoCache = Regex.Replace(note.InfoCache, "(?<=NewMaturityDate\":\")[^\"]+ (?= \")", + date.ToString("yyyy-MM-dd")); } model.CurrentPositionDetails = GetCurrentPositionDetailsModel(model.ConfirmationNo); @@ -311,6 +592,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service { model.BizID = note.BizId; } + model.ExceID = base.formatExceID(SACReportNotesCache); result.Add(model); ReportStatus.AddCacheInfo(CacheKey, cacheValue); @@ -331,6 +613,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service noteList.Add(note); } } + return result; } @@ -347,6 +630,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service //第一列空白说明数据结束了; break; } + if (dt.Rows[i][0]?.ToString().Trim() != confirmationNo) { continue; @@ -370,16 +654,20 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service result.Add(model); } } + return result; } - private string formatInfoTag(SwapDurationManagementModel model, bool suffixType = false, string extensionTimeInfo = "") + private string formatInfoTag(SwapDurationManagementModel model, bool suffixType = false, + string extensionTimeInfo = "") { - var result = $"{BusiDataType}_{model.ConfirmationNo.Replace("_", "-")}_{(string.IsNullOrWhiteSpace(extensionTimeInfo) ? "了结" : $"_{extensionTimeInfo}_展期")}_{model.DurationEventNO}_"; + var result = + $"{BusiDataType}_{model.ConfirmationNo.Replace("_", "-")}_{(string.IsNullOrWhiteSpace(extensionTimeInfo) ? "了结" : $"_{extensionTimeInfo}_展期")}_{model.DurationEventNO}_"; if (suffixType) { result = $"{result}{_operationType}"; } + return result; } @@ -390,6 +678,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service { throw new ServiceException($"InfoTag信息不匹配:{infoTag}"); } + originalCode = arr[1]; arr[1] = newCode.Replace("_", "-"); return string.Join("_", arr); @@ -433,20 +722,20 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service }; listRoot.Add(temp); } - } } + if (listRoot.Count > 0) { var errMsg = new SacInfo("SwapDurationManagement", i) { - FieldValue = item.ConfirmationNo, - SubMaps = new List(listRoot) + FieldValue = item.ConfirmationNo, SubMaps = new List(listRoot) }; result.Add(errMsg); } } } + checkStatus = result.Count > 0; return result; } @@ -463,7 +752,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service catch (Exception e) { LogFactory.GetLogger().Error(e); - }; + } } for (var i = 0; i < noteList.Count; i++) diff --git a/YLErpWeb/Views/Client_Rating/ClientRatingLogList.cshtml b/YLErpWeb/Views/Client_Rating/ClientRatingLogList.cshtml index 38be11ad..32f544d4 100644 --- a/YLErpWeb/Views/Client_Rating/ClientRatingLogList.cshtml +++ b/YLErpWeb/Views/Client_Rating/ClientRatingLogList.cshtml @@ -14,30 +14,31 @@ }
- - - - - - - - - - - - - - - - - @foreach (var item in Model) - { - - - - - - - } - -
操作时间操作人操作内容说明
@(item.OptDate.ToString("yyyy-MM-dd HH:mm:ss"))@(item.OptName)@(item.OptType)@(item.Changes)
+ + + + + + + + + + + + + + + + + @foreach (var item in Model) + { + + + + + + + } + +
操作时间操作人操作内容说明
@(item.OptDate.ToString("yyyy-MM-dd HH:mm:ss"))@(item.OptName)@(item.OptType)@(item.Changes)
+
diff --git a/YLErpWeb/Views/SwapRate/OperationHistory.cshtml b/YLErpWeb/Views/SwapRate/OperationHistory.cshtml index 89184881..9e7301b1 100644 --- a/YLErpWeb/Views/SwapRate/OperationHistory.cshtml +++ b/YLErpWeb/Views/SwapRate/OperationHistory.cshtml @@ -53,3 +53,4 @@ } + \ No newline at end of file diff --git a/YLErpWeb/Views/client/ClientAssessmentHistoryLog.cshtml b/YLErpWeb/Views/client/ClientAssessmentHistoryLog.cshtml index 5d6ff09d..39844709 100644 --- a/YLErpWeb/Views/client/ClientAssessmentHistoryLog.cshtml +++ b/YLErpWeb/Views/client/ClientAssessmentHistoryLog.cshtml @@ -14,30 +14,31 @@ }
- - - - - - - - - - - - - - - - - @foreach (var item in Model) - { - - - - - - - } - -
评估日期评估有效期操作人操作时间
@(item.EvaluateDate)@(item.EvaluateOfValidity)@(item.OptName)@(item.OptDate)
\ No newline at end of file + + + + + + + + + + + + + + + + + @foreach (var item in Model) + { + + + + + + + } + +
评估日期评估有效期操作人操作时间
@(item.EvaluateDate)@(item.EvaluateOfValidity)@(item.OptName)@(item.OptDate)
+
\ No newline at end of file diff --git a/YLErpWeb/Views/client/ClientOperationHistory.cshtml b/YLErpWeb/Views/client/ClientOperationHistory.cshtml index 2b179c81..9d14e57b 100644 --- a/YLErpWeb/Views/client/ClientOperationHistory.cshtml +++ b/YLErpWeb/Views/client/ClientOperationHistory.cshtml @@ -14,42 +14,43 @@ }
- - - - - - - - - - - - - - - - - @foreach (var item in Model) - { - - - - - + + } + +
操作时间操作人操作内容说明
@(item.OptDate.ToString("yyyy-MM-dd HH:mm:ss"))@(item.OptName)@(item.OptType) - @{ - if (!string.IsNullOrWhiteSpace(item.Changes)) - { - var change = item.Changes.Split(';'); - foreach (var c in change) - { - @c -
- } - } + + + + + + + + + + + + + + + + + @foreach (var item in Model) + { + + + + + - - } - -
操作时间操作人操作内容说明
@(item.OptDate.ToString("yyyy-MM-dd HH:mm:ss"))@(item.OptName)@(item.OptType) + @{ + if (!string.IsNullOrWhiteSpace(item.Changes)) + { + var change = item.Changes.Split(';'); + foreach (var c in change) + { + @c +
} -
+ } + } +
+
diff --git a/YLErpWeb/Views/client/ClientTemplateChoose.cshtml b/YLErpWeb/Views/client/ClientTemplateChoose.cshtml index 5ef4f072..90d35650 100644 --- a/YLErpWeb/Views/client/ClientTemplateChoose.cshtml +++ b/YLErpWeb/Views/client/ClientTemplateChoose.cshtml @@ -84,7 +84,7 @@ 客户名 文件模板类型 - 文件模板 + 文件模板 操作 @foreach (var item in Model) diff --git a/YLErpWeb/Views/entryexit/ClientCashLogList.cshtml b/YLErpWeb/Views/entryexit/ClientCashLogList.cshtml index b1858c76..a04880dc 100644 --- a/YLErpWeb/Views/entryexit/ClientCashLogList.cshtml +++ b/YLErpWeb/Views/entryexit/ClientCashLogList.cshtml @@ -41,3 +41,4 @@ } + \ No newline at end of file diff --git a/YLErpWeb/Views/trade/submissionFieldsHistory.cshtml b/YLErpWeb/Views/trade/submissionFieldsHistory.cshtml index 2a0fbbfb..be6d7bcd 100644 --- a/YLErpWeb/Views/trade/submissionFieldsHistory.cshtml +++ b/YLErpWeb/Views/trade/submissionFieldsHistory.cshtml @@ -19,7 +19,7 @@ - +