using BaseOUDAL; using OfficeOpenXml; using OfficeOpenXml.Style; using System.Dynamic; using System.Linq.Expressions; using System.Text.RegularExpressions; using YieldChain.Helpers; using YLErp.BLL; using YLErp.DBModels.Consts; using YLErp.Enums; using YLErp.Helpers; using YLErp.Model; using YLErp.Modules.CalculationModule; using YLErp.Modules.DataCacheModule; using YLErp.MsOffice; using YLErp.Office; using YLErp.Office.Converters; namespace YLErp.Modules.TradeModule { /// /// 交易明细查询服务 /// public class TradeDetailsQueryService : YLBaseService { public TradeDetailsQueryService(OptUserInfo userInfo) : base(userInfo) { } public TradeDetailsQueryService(YLBaseService baseService) : base(baseService) { } public TradeDetailsReport TradeDetailsReport { private set; get; } private void BuildTradePredicate(TradeDetailsReq req, int groupTradeId, out Expression> tradPredicate, out Expression> tradeCashPredicate) { if (groupTradeId > 0) { tradPredicate = PredicateBuilder.True().And(x => x.ParentTradeId == groupTradeId); } else { //交易明细页面:组合互换 提前终止和到期都按照子交易展示 if (req.DetailStatuses == "提前终止" || req.DetailStatuses == "到期") { tradPredicate = PredicateBuilder.True().And(x => x.IsGroup == 0 || x.IsGroup == 1 || (x.IsGroup == 2 && x.TradeType == "收益互换")); } //交易明细页面:组合互换 成交按照主交易可展开形式展示 else if (req.DetailStatuses == "成交") { tradPredicate = PredicateBuilder.True().And(x => x.IsGroup == 0 || x.IsGroup == 1); } //交易明细导出:组合互换都按照子交易展示 else { tradPredicate = PredicateBuilder.True().And(x => x.IsGroup == 0 || (x.IsGroup == 1 && x.TradeType == "结构化交易") || (x.IsGroup == 2 && x.TradeType == "收益互换")); } } if (req.UserAssetUnits != null && req.UserAssetUnits.Any()) { tradPredicate = tradPredicate.And(t => req.UserAssetUnits.Contains(t.AssetId)); } var endDate = req.EndDate.Value; tradPredicate = tradPredicate.And(t => t.TradeDate <= endDate && t.ValidState != "InValid"); if (req.TradeTypes != null && req.TradeTypes.Any(n => !string.IsNullOrEmpty(n))) { var types = req.TradeTypes; tradPredicate = tradPredicate.And(t => types.Contains(t.TradeType) || types.Contains(t.StructureType)); } if (!string.IsNullOrWhiteSpace(req.StructureType)) { tradPredicate = tradPredicate.And(t => t.StructureType.Contains(req.StructureType)); } var clientIdsInt = new List(); if (!string.IsNullOrWhiteSpace(req.ClientIds)) { clientIdsInt.AddRange(req.ClientIdsInt); } else if (req.ClientId > 0) { clientIdsInt.Add(req.ClientId); } if (req.ParentFlag) { var clientIdList = DataCacheProvider.GetClientDataSource().AsQueryable(O => clientIdsInt.Contains(O.ParentId)).Select(O => O.id).ToList().ToHashSet(); clientIdsInt.AddRange(clientIdList); } tradPredicate = tradPredicate.And(t => clientIdsInt.Contains(t.ClientId)); //----------------------------------------------- // trade_cash predicate //----------------------------------------------- var detailStatuses = req.DetailStatuses.TrimToEmpty(); var tradCashPredicates = new Expression>[3]; if (detailStatuses.Contains("成交")) { var tcPredicate = PredicateBuilder.Create(tc => tc.Action == ClientCashInCashOut.系统操作_期权费); if (req.StartDate != null) { tcPredicate = tcPredicate.And(t => t.ValueDate >= req.StartDate); } tradCashPredicates[0] = tcPredicate; } if (detailStatuses.Contains("提前终止")) { var tcPredicate = PredicateBuilder.Create(tc => ((tc.ValueDate <= endDate && tc.HappenedDate == null) || tc.HappenedDate <= endDate) && (tc.Action == ClientCashInCashOut.系统操作_平仓费 || (tc.Action == ClientCashInCashOut.系统操作_行权费 && tc.ExerciseWay == TradeCashExerciseWayEnum.提前终止行权) || (tc.ExerciseWay != TradeCashExerciseWayEnum.到期行权 && tc.IsLastAction))); if (req.StartDate != null) { tcPredicate = tcPredicate.And(tc => tc.ValueDate >= req.StartDate); } tradCashPredicates[1] = tcPredicate; } if (detailStatuses.Contains("到期")) { var tcPredicate = PredicateBuilder.Create(tc => ((tc.ValueDate <= endDate && tc.HappenedDate == null) || tc.HappenedDate <= endDate) && (tc.Action == ClientCashInCashOut.系统操作_行权费 || tc.Action == ClientCashInCashOut.系统操作_互换) && tc.ExerciseWay == TradeCashExerciseWayEnum.到期行权); if (req.StartDate != null) { tcPredicate = tcPredicate.And(tc => tc.ValueDate >= req.StartDate); } tradCashPredicates[2] = tcPredicate; } tradeCashPredicate = PredicateBuilder.False(); for (var i = 0; i < tradCashPredicates.Length; i++) { if (tradCashPredicates[i] != null) { tradeCashPredicate = tradeCashPredicate.Or(tradCashPredicates[i]); } } tradeCashPredicate = PredicateBuilder.Create( tradeCash => tradeCash.ValidState != ConsGlobal.InValid && !tradeCash.IsDeleted).And(tradeCashPredicate); } /// /// 查询客户交易明细 /// public SearchListResult SearchTradeDetails(TradeDetailsReq req, int groupTradeId = 0) { if (req.ClientId < 1 && string.IsNullOrWhiteSpace(req.ClientIds)) { return new SearchListResult(); } if (req.EndDate == null) { throw new ServiceException("请选择结束日期"); } if (req.StartDate != null && req.StartDate > req.EndDate) { throw new ServiceException("起始日期不能大于结束日期"); } BuildTradePredicate(req, groupTradeId, out var tradPredicate, out var tradeCashPredicate); var query = from td in DbContext.trade.Where(tradPredicate) join tc in DbContext.trade_cash.Where(tradeCashPredicate) on td.id equals tc.TradeId join et in DbContext.eod_trade.Where(O => O.ValueDate == req.EndDate.Value) on td.id equals et.TradeId into tempEt from et in tempEt.DefaultIfEmpty() select new { et, OtcTradeDetail = new OtcTradeDetail { id = td.id, TradeNumber = td.TradeNumber, BuySell = td.BuySell, TradeDate = td.TradeDate, ExerciseDate = td.ExerciseDate, TradeType = td.IsGroup == 1 ? td.StructureType : td.TradeType, UnderlyingCode = td.UnderlyingCode, SpotPrice = td.SpotPrice, TradeSinglePrice = td.TradeSinglePrice, TradePrice = td.TradePrice, Lots = td.Lots, OriginalNotional = td.OriginalNotional, Strike = td.Strike, IsMoneynessOption = td.IsMoneynessOption, BasisUnderlyingCode = td.BasisUnderlyingCode, BasisGap = td.BasisGap, UnderlyingInstrumentType = td.UnderlyingInstrumentType, StockEqvNotional = td.StockEqvNotional, OriginalStockEqvNotional = td.OriginalStockEqvNotional, IsUsePremiumRate = td.IsUsePremiumRate, TradeStatus = td.TradeStatus, StructureType = td.StructureType, PremiumRate = td.PremiumRate, ExerciseMode = td.ExerciseMode, OptionType = td.OptionType, AnnualizeFactor = td.AnnualizeFactor, TcId = tc.id, TcValueDate = tc.ValueDate, TcAction = tc.Action, TcAmount = tc.Amount, TcNotional = tc.Notional, TcTradeAmount = tc.TradeAmount, TcUnwindPrice = tc.UnwindPrice, TcUnwindPricePercent = tc.UnwindPricePercentRate, TcUnwindNotional = tc.UnwindNotional, TcUnwindTradeAmount = tc.UnwindTradeAmount, TcUnwindPercent = tc.UnwindPercentRate, TcExerciseWay = tc.ExerciseWay, TcFinalPrice = tc.FinalPrice, ParticipationRate = td.ParticipationRate, PrincipalRate = td.PrincipalRate, NoRiskRate = td.NoRiskRate, UnderlyingAssetName = td.UnderlyingAssetName, IsGroup = td.IsGroup, ClientName = td.ClientName, ExtendInfo = td.ExtendInfo, IsLastAction = tc.IsLastAction //ActualStrike = td.ActualStrike, } }; if (req.sidx.IsNullOrWhiteSpace()) { req.sidx = "OtcTradeDetail.TcValueDate,OtcTradeDetail.TcId"; req.sord = "desc"; } var tempRetListResult = query.ToSearchList(req); foreach (var item in tempRetListResult.rows) { if (item.OtcTradeDetail.IsLastAction) { if (item.OtcTradeDetail.TradeType == "凤凰期权" || item.OtcTradeDetail.IsGroup == 1) { var tradeCashs = DbContext.trade_cash.Where(y => y.ValidState != "InValid" && y.TradeId == item.OtcTradeDetail.id && y.Action == "系统操作-票息" && y.id != item.OtcTradeDetail.TcId); if (tradeCashs.Any()) { item.OtcTradeDetail.TcAmount += tradeCashs.Sum(y => y.Amount); } } else if (item.OtcTradeDetail.TradeType == "收益互换") { var tradeCashs = DbContext.trade_cash.Where(y => y.ValidState != "InValid" && y.TradeId == item.OtcTradeDetail.id && y.Action == "系统操作-互换" && y.id != item.OtcTradeDetail.TcId); if (tradeCashs.Any()) { item.OtcTradeDetail.TcAmount += tradeCashs.Sum(y => y.Amount); } } } if (item.OtcTradeDetail.IsGroup == 1) { var childTradeCashs = DbContext.trade_cash.Where(x => x.ParentTradeCashId == item.OtcTradeDetail.TcId).ToList(); var childTradeIds = childTradeCashs.Select(x => x.TradeId).Distinct().ToList(); var childTrades = DbContext.trade.Where(x => childTradeIds.Contains(x.id)).ToList(); item.OtcTradeDetail.TcTradePrice = 0; childTradeCashs.ForEach(x => { var trade = childTrades.FirstOrDefault(y => y.id == x.TradeId); item.OtcTradeDetail.TcTradePrice += (x.UnwindPercentRate * trade?.TradePrice * (trade?.BuySell == "买入" ? -1 : 1)) ?? 0; }); } item.OtcTradeDetail.TradeSinglePrice = Math.Abs(item.OtcTradeDetail.TradeSinglePrice ?? 0); if (item.et == null) { continue; } item.OtcTradeDetail.SpotPrice = item.et.trade.SpotPrice; item.OtcTradeDetail.TradeSinglePrice = Math.Abs(item.et.trade.TradeSinglePrice ?? 0); item.OtcTradeDetail.TradePrice = item.et.trade.TradePrice; item.OtcTradeDetail.OriginalNotional = item.et.trade.OriginalNotional; item.OtcTradeDetail.Strike = item.et.trade.Strike; item.OtcTradeDetail.OriginalStockEqvNotional = item.et.trade.OriginalStockEqvNotional; } var retListResult = new SearchListResult { Msg = tempRetListResult.Msg, page = tempRetListResult.page, records = tempRetListResult.records, rows = tempRetListResult.rows.Select(O => O.OtcTradeDetail), total = tempRetListResult.total }; dynamic sum = new ExpandoObject(); if (retListResult.rows.Any()) { sum.WinLossSum = retListResult.rows.Sum(a => a.WinLoss); sum.TradePriceSum = retListResult.rows.Sum(a => a.TradePrice * (a.BuySell == "买入" && a.TradeType != "远期" ? -1 : 1)); sum.MinusAmountSum = retListResult.rows.Sum(a => a.TcAmount); sum.StockEqvNotionalSum = retListResult.rows.Select(x => new { x.id, x.OriginalStockEqvNotional }) .Distinct().Sum(q => q.OriginalStockEqvNotional); } retListResult.Sum = sum; var underlyinglist = underlying_managerBLL.GetQuery(); foreach (var td in retListResult.rows) { if (td.TradeType == "亚式期权") { var baseReq = FixingService.GetRequestBase(valuedateBLL.ValueDate, td); var strikeReq = new AsianOptionStrikeRequest(baseReq) { IsMoneynessOption = td.IsMoneynessOption == "是", SpotPrice = td.SpotPrice, Strike = td.Strike, }; td.ActualStrike = trade_asian_optionBLL.GetAsianStrikePrice(strikeReq, null); } else { td.ActualStrike = td.IsMoneynessOption == "是" ? (td.SpotPrice * td.Strike) : td.Strike; } var CountRatio = UnderlyingDataProvider.GetCountRatio(td.UnderlyingCode); if (!ConsTrade.TradeTypesForHedge.Contains(td.TradeType)) { td.TradeOriginalAmount = td.OriginalNotional / CountRatio; } td.CountRatio = CountRatio; if (td.TradeType == "合成价差期权") { td.SyntheticUnderlyingTipsInfo = synthetic_underlyingBLL.GetUnderlyingTipsInfo(td.UnderlyingCode); } } return retListResult; } private string ConfirmYesDanzhang(SearchListResult tradelist, Client client, TradeDetailsReq req, string biaoTou = null, string biaoWei = null) { var dic = new Dictionary(); var table1 = new List>(); var table2 = new List>(); var table3 = new List>(); var contractGroupList1 = tradelist.rows.Where(q => q.TcAction == ClientCashInCashOut.系统操作_期权费).ToList(); var contractGroupList2 = tradelist.rows.Where(q => q.TcAction == ClientCashInCashOut.系统操作_平仓费 || (q.TcAction == ClientCashInCashOut.系统操作_行权费 && q.TcExerciseWay == TradeCashExerciseWayEnum.提前终止行权)).ToList(); var contractGroupList3 = tradelist.rows.Where(q => (q.TcAction == ClientCashInCashOut.系统操作_行权费 || q.TcAction == ClientCashInCashOut.系统操作_互换) && q.TcExerciseWay == TradeCashExerciseWayEnum.到期行权).ToList(); foreach (var td in contractGroupList1) { var row1 = new Dictionary(); var va = new TradeSingleDetailReport(td); row1["{{table1.交易编号}}"] = td.TradeNumber; row1["{{table1.交易方向}}"] = va.BuySell; row1["{{table1.交易日期}}"] = $"{td.TradeDate:yyyy/MM/dd}"; row1["{{table1.到期日期}}"] = $"{td.ExerciseDate:yyyy/MM/dd}"; row1["{{table1.期权类型}}"] = va.TradeMultipleType; row1["{{table1.标的代码}}"] = td.UnderlyingCode; row1["{{table1.期初价格}}"] = $"{va.InitialSpotPrice_Calc}"; row1["{{table1.执行价格}}"] = $"{va.StrikeString}"; row1["{{table1.权利金}}"] = $"{va.TradeSinglePriceString}"; row1["{{table1.交易数量}}"] = $"{va.TradeOriginalAmount:F2}"; row1["{{table1.交易总额}}"] = $"{va.TradePrice:F2}"; table1.Add(row1); } foreach (var td in contractGroupList2) { var row2 = new Dictionary(); var va = new TradeSingleDetailReport(td); row2["{{table2.交易编号}}"] = td.TradeNumber; row2["{{table2.交易方向}}"] = va.BuySell; row2["{{table2.交易日期}}"] = $"{td.TradeDate:yyyy/MM/dd}"; row2["{{table2.到期日期}}"] = $"{td.ExerciseDate:yyyy/MM/dd}"; row2["{{table2.期权类型}}"] = va.TradeMultipleType; row2["{{table2.标的代码}}"] = td.UnderlyingCode; row2["{{table2.执行价格}}"] = $"{va.StrikeString}"; row2["{{table2.权利金}}"] = $"{va.TradeSinglePriceString}"; row2["{{table2.交易数量}}"] = $"{va.TradeOriginalAmount:F2}"; row2["{{table2.交易总额}}"] = $"{va.TradePrice:F2}"; row2["{{table2.提前终止类型}}"] = va.UnwindType; row2["{{table2.提前终止日期}}"] = $"{va.UnwindDate}"; row2["{{table2.提前终止数量}}"] = $"{va.UnwindTradeAmount}"; row2["{{table2.平仓标的价格}}"] = $"{va.FinalPrice}"; row2["{{table2.平仓价格行权收益}}"] = $"{va.SingleMinusAmountString}"; row2["{{table2.提前终止总额}}"] = $"{va.MinusAmount:F2}"; row2["{{table2.实现盈亏}}"] = $"{va.WinLoss:F2}"; table2.Add(row2); } foreach (var td in contractGroupList3) { var row3 = new Dictionary(); var va = new TradeSingleDetailReport(td); row3["{{table3.交易编号}}"] = td.TradeNumber; row3["{{table3.交易方向}}"] = va.BuySell; row3["{{table3.交易日期}}"] = $"{td.TradeDate:yyyy/MM/dd}"; row3["{{table3.到期日期}}"] = $"{td.ExerciseDate:yyyy/MM/dd}"; row3["{{table3.期权类型}}"] = va.TradeMultipleType; row3["{{table3.标的代码}}"] = td.UnderlyingCode; row3["{{table3.执行价格}}"] = $"{va.StrikeString}"; row3["{{table3.权利金}}"] = $"{va.TradeSinglePriceString}"; row3["{{table3.交易数量}}"] = $"{va.TradeOriginalAmount:F2}"; row3["{{table3.交易总额}}"] = $"{va.TradePrice:F2}"; row3["{{table3.到期状态}}"] = va.ExerciseType; row3["{{table3.到期数量}}"] = $"{va.UnwindTradeAmount:F2}"; row3["{{table3.到期标的价格}}"] = $"{va.FinalPrice:F2}"; row3["{{table3.到期收益}}"] = $"{va.SingleMinusAmountString:F2}"; row3["{{table3.到期收益总额}}"] = $"{va.MinusAmount:F2}"; row3["{{table3.实现盈亏}}"] = $"{va.WinLoss:F2}"; table3.Add(row3); } dic["{{客户编号}}"] = client.Number; dic["{{公司名称}}"] = client.Name; dic["{{甲方}}"] = PS.Config.CompanyFullName; dic["{{table1."] = table1; dic["{{table2."] = table2; dic["{{table3."] = table3; dic["{{合同日期}}"] = $"{DateTime.Now.ToString("yyyy年MM月dd日")}";//ValueDate dic["{{了结日期1}}"] = $"{req.StartDate:yyyy/MM/dd}"; dic["{{了结日期2}}"] = $"{req.EndDate:yyyy/MM/dd}"; var targetFolder = req.OutputFolder; if (string.IsNullOrEmpty(targetFolder)) { var date = req.EndDate; targetFolder = OtcAppContext.MapPath($"~/App_Docs/Download/{date:yyyyMM}"); } var templateFile = OtcAppContext.MapPath("~/App_Docs/导出模板/单章-场外衍生品交易结算确认书(交易明细).docx"); string FileName; var startDate = req.StartDate; if (startDate == DateTime.MinValue) { FileName = $"交易明细_{req.EndDate:MMdd}_{client.Name}.docx"; } else { FileName = $"交易明细_{startDate:MMdd}_{req.EndDate:MMdd}_{client.Name}.docx"; } var excelFilePath = Path.Combine(targetFolder, FileName); MsWordTempalteHelper.GenerateFromTemplate(templateFile, dic, excelFilePath, true); var report = new TradeDetailsReport { CreatedModel = new TradeDetailsModel(), FinishedModel = new TradeDetailsModel(), MatureModel = new TradeDetailsModel(), ClientId = client.id, ClientName = client.Name, ClientFullName = client.Name, ClientNumber = client.Number, ClientAbbreviation = client.Abbreviation, CompanyName = PS.Config.CompanyFullName, ReportStart = req.StartDate == null ? DateTime.MinValue : req.StartDate.Value, ReportEnd = req.EndDate.Value }; var contractGroupList = tradelist.rows.Where(q => q.TcAction == ClientCashInCashOut.系统操作_期权费).ToList(); contractGroupList.ForEach(x => { if (x.TradeType == "结构化交易" && x.IsGroup == 1) { x.TradeType = x.StructureType; } }); new TradeExtendService(this).SetTradeExtendWithCnKey(contractGroupList, true); var tradeTypes = contractGroupList.Select(x => x.TradeType).ToHashSet(); report.CreatedModel.TradeList = contractGroupList.Select(g => new TradeSingleDetailReport(g)).ToList(); report.CreatedModel.Tradelist_Vanilla = contractGroupList.Where(c => c.TradeType == "香草期权").Select(g => new TradeSingleDetailReport(g)).ToList(); tradeTypes.Remove("香草期权"); report.CreatedModel.Tradelist_Forward = contractGroupList.Where(c => c.TradeType == "远期").Select(g => new TradeSingleDetailReport(g)).ToList(); tradeTypes.Remove("远期"); report.CreatedModel.Tradelist_Asian = contractGroupList.Where(c => c.TradeType == "亚式期权").Select(g => new TradeSingleDetailReport(g)).ToList(); tradeTypes.Remove("亚式期权"); report.CreatedModel.TradeList_Binary = contractGroupList.Where(c => c.TradeType == "二元期权").Select(g => new TradeSingleDetailReport(g)).ToList(); tradeTypes.Remove("二元期权"); report.CreatedModel.TradeList_Barrier = contractGroupList.Where(c => c.TradeType == "障碍期权").Select(g => new TradeSingleDetailReport(g)).ToList(); tradeTypes.Remove("障碍期权"); report.CreatedModel.TradeList_DbShark = contractGroupList.Where(c => c.TradeType == "双鲨期权").Select(g => new TradeSingleDetailReport(g)).ToList(); tradeTypes.Remove("双鲨期权"); report.CreatedModel.TradeList_Autocall = contractGroupList.Where(c => c.TradeType == "凤凰期权").Select(g => new TradeSingleDetailReport(g)).ToList(); tradeTypes.Remove("凤凰期权"); report.CreatedModel.TradeList_Snowball = contractGroupList.Where(c => c.TradeType == "雪球期权").Select(g => new TradeSingleDetailReport(g)).ToList(); tradeTypes.Remove("雪球期权"); report.CreatedModel.TradeList_RangeAcc = contractGroupList.Where(c => c.TradeType == "区间累积期权").Select(g => new TradeSingleDetailReport(g)).ToList(); tradeTypes.Remove("区间累积期权"); report.CreatedModel.TradeList_AirBag = contractGroupList.Where(c => c.TradeType == "气囊结构").Select(g => new TradeSingleDetailReport(g)).ToList(); tradeTypes.Remove("气囊结构"); report.CreatedModel.TradeList_PayoffSwap = contractGroupList.Where(c => c.TradeType == "收益互换").Select(g => new TradeSingleDetailReport(g)).ToList(); tradeTypes.Remove("收益互换"); report.CreatedModel.TradeList_Custom = contractGroupList.Where(c => c.TradeType == "自定义交易").Select(g => new TradeSingleDetailReport(g)).ToList(); var extendInfos = report.CreatedModel.TradeList_Custom.Where(x => x.TdDetail.ExtendInfo != null).Select(x => x.TdDetail).ToList(); var propertys = new List(); extendInfos.ForEach(x => { propertys.AddRange(x.Propertys); }); report.CreatedModel.PropertyNames_Custom = propertys.Select(x => x.name).Distinct().ToList(); tradeTypes.Remove("自定义交易"); report.CreatedModel.TradeList_SSpread = contractGroupList.Where(c => c.TradeType == "合成价差期权").Select(g => new TradeSingleDetailReport(g)).ToList(); tradeTypes.Remove("合成价差期权"); report.CreatedModel.TradeList_Enhance = contractGroupList.Where(c => c.TradeType == "收益增强结构").Select(g => new TradeSingleDetailReport(g)).ToList(); tradeTypes.Remove("收益增强结构"); report.CreatedModel.TradeList_Cashflow = contractGroupList.Where(c => c.TradeType == "现金流交易").Select(g => new TradeSingleDetailReport(g)).ToList(); tradeTypes.Remove("现金流交易"); report.CreatedModel.TradeList_Accumulator = contractGroupList.Where(c => c.TradeType == "累计期权").Select(g => new TradeSingleDetailReport(g)).ToList(); tradeTypes.Remove("累计期权"); report.CreatedModel.Tradelist_Risky = contractGroupList.Where(c => c.TradeType == "Risky期权").Select(g => new TradeSingleDetailReport(g)).ToList(); tradeTypes.Remove("Risky期权"); report.CreatedModel.TradeList_Others = contractGroupList.Where(c => tradeTypes.Contains(c.TradeType)).Select(g => new TradeSingleDetailReport(g)).ToList(); Func sumf = q => q.TradePrice; report.CreatedModel.VanillaTradePriceSum = report.CreatedTradeList_Vanilla.Sum(sumf); report.CreatedModel.AsianTradePriceSum = report.CreatedTradeList_Asian.Sum(sumf); report.CreatedModel.BinaryTradePriceSum = report.CreatedTradeList_Binary.Sum(sumf); report.CreatedModel.BarrierTradePriceSum = report.CreatedTradeList_Barrier.Sum(sumf); report.CreatedModel.DbSharkTradePriceSum = report.CreatedTradeList_DbShark.Sum(sumf); report.CreatedModel.AutocallTradePriceSum = report.CreatedTradeList_Autocall.Sum(sumf); report.CreatedModel.SnowballTradePriceSum = report.CreatedTradeList_Snowball.Sum(sumf); report.CreatedModel.RangeAccTradePriceSum = report.CreatedTradeList_RangeAcc.Sum(sumf); report.CreatedModel.AirBagTradePriceSum = report.CreatedTradeList_AirBag.Sum(sumf); report.CreatedModel.CustomTradePriceSum = report.CreatedTradeList_Custom.Sum(sumf); report.CreatedModel.SSpreadTradePriceSum = report.CreatedTradeList_SSpread.Sum(sumf); report.CreatedModel.CashflowTradePriceSum = report.CreatedTradeList_Cashflow.Sum(sumf); report.CreatedModel.AccumulatorTradePriceSum = report.CreatedTradeList_Accumulator.Sum(sumf); contractGroupList = tradelist.rows.Where(q => q.TcAction == ClientCashInCashOut.系统操作_平仓费 || (q.TcAction == ClientCashInCashOut.系统操作_行权费 && q.TcExerciseWay == TradeCashExerciseWayEnum.提前终止行权)).ToList(); report.FinishedModel.TradePriceSum = contractGroupList.Select(x => new { x.id, x.TradePrice, x.BuySell }) .Distinct().Sum(q => (q.TradePrice ?? 0) * ("卖出".Equals(q.BuySell) ? -1 : 1)); report.FinishedModel.MinusAmountSum = contractGroupList.Sum(q => q.TcAmount ?? 0); report.FinishedModel.WinLossSum = (contractGroupList.Sum(q => q.WinLoss)) ?? 0; report.FinishedModel.TradeList = contractGroupList.Select(g => new TradeSingleDetailReport(g)).ToList(); contractGroupList = tradelist.rows.Where(q => (q.TcAction == ClientCashInCashOut.系统操作_行权费 || q.TcAction == ClientCashInCashOut.系统操作_互换) && q.TcExerciseWay == TradeCashExerciseWayEnum.到期行权).ToList(); report.MatureModel.TradePriceSum = contractGroupList.Select(x => new { x.id, x.TradePrice, x.BuySell }) .Distinct().Sum(q => (q.TradePrice ?? 0) * ("卖出".Equals(q.BuySell) ? -1 : 1)); report.MatureModel.MinusAmountSum = contractGroupList.Sum(q => q.TcAmount ?? 0); report.MatureModel.WinLossSum = (contractGroupList.Sum(q => q.WinLoss)) ?? 0; report.MatureModel.TradeList = contractGroupList.Select(g => new TradeSingleDetailReport(g)).ToList(); #region 处理表头表尾 var biaoTouList = Regex.Split(biaoTou, "

", RegexOptions.IgnoreCase).Where(x => !string.IsNullOrWhiteSpace(x)).ToList(); var newBiaoTouList = new List(); biaoTouList.ForEach(x => { x = Regex.Replace(x, "<[^>]+>", ""); x = Regex.Replace(x, "&[^;]+;", ""); newBiaoTouList.Add(x); }); report.BiaoTouLines = newBiaoTouList; report.BiaoTou = string.Join("\n", newBiaoTouList); var biaoWeiList = Regex.Split(biaoWei, "

", RegexOptions.IgnoreCase).Where(x => !string.IsNullOrWhiteSpace(x)).ToList(); var newBiaoWeiList = new List(); biaoWeiList.ForEach(x => { x = Regex.Replace(x, "<[^>]+>", ""); x = Regex.Replace(x, "&[^;]+;", ""); newBiaoWeiList.Add(x); }); report.BiaoWeiLines = newBiaoWeiList; report.BiaoWei = string.Join("\n", newBiaoWeiList); #endregion report.OutputFolder = req.OutputFolder; TradeDetailsReport = report; return excelFilePath; } private string ConfirmDanzhang(SearchListResult resultList, Client client, TradeDetailsReq req, string biaoTou = null, string biaoWei = null, bool isCreateConfirmBookModeDirectory = false, bool GenerateTradeDetails = true) { //国君要求如果没有交易明细就不要生成 //20210416王锦麟注释掉了这三行 //20211014国君沈小杨+镒链翁敏华要求改回来 //如果要注释下面这三行代码请写出理由 if (!resultList.rows.Any()) { throw new ServiceException(client.Name + "没有交易明细"); } var report = new TradeDetailsReport { CreatedModel = new TradeDetailsModel(), FinishedModel = new TradeDetailsModel(), MatureModel = new TradeDetailsModel() }; var contractGroupList = resultList.rows.Where(q => q.TcAction == ClientCashInCashOut.系统操作_期权费).ToList(); contractGroupList.ForEach(x => { if (x.TradeType == "结构化交易" && x.IsGroup == 1) { x.TradeType = x.StructureType; } }); new TradeExtendService(this).SetTradeExtendWithCnKey(contractGroupList, true); var tradeTypes = contractGroupList.Select(x => x.TradeType).ToHashSet(); report.CreatedModel.TradeList = contractGroupList.Select(g => new TradeSingleDetailReport(g)).ToList(); report.CreatedModel.Tradelist_Vanilla = contractGroupList.Where(c => c.TradeType == "香草期权").Select(g => new TradeSingleDetailReport(g)).ToList(); tradeTypes.Remove("香草期权"); report.CreatedModel.Tradelist_Forward = contractGroupList.Where(c => c.TradeType == "远期").Select(g => new TradeSingleDetailReport(g)).ToList(); tradeTypes.Remove("远期"); report.CreatedModel.Tradelist_Asian = contractGroupList.Where(c => c.TradeType == "亚式期权").Select(g => new TradeSingleDetailReport(g)).ToList(); tradeTypes.Remove("亚式期权"); report.CreatedModel.TradeList_Binary = contractGroupList.Where(c => c.TradeType == "二元期权").Select(g => new TradeSingleDetailReport(g)).ToList(); tradeTypes.Remove("二元期权"); report.CreatedModel.TradeList_Barrier = contractGroupList.Where(c => c.TradeType == "障碍期权").Select(g => new TradeSingleDetailReport(g)).ToList(); tradeTypes.Remove("障碍期权"); report.CreatedModel.TradeList_DbShark = contractGroupList.Where(c => c.TradeType == "双鲨期权").Select(g => new TradeSingleDetailReport(g)).ToList(); tradeTypes.Remove("双鲨期权"); report.CreatedModel.TradeList_Autocall = contractGroupList.Where(c => c.TradeType == "凤凰期权").Select(g => new TradeSingleDetailReport(g)).ToList(); tradeTypes.Remove("凤凰期权"); report.CreatedModel.TradeList_Snowball = contractGroupList.Where(c => c.TradeType == "雪球期权").Select(g => new TradeSingleDetailReport(g)).ToList(); tradeTypes.Remove("雪球期权"); report.CreatedModel.TradeList_RangeAcc = contractGroupList.Where(c => c.TradeType == "区间累积期权").Select(g => new TradeSingleDetailReport(g)).ToList(); tradeTypes.Remove("区间累积期权"); report.CreatedModel.TradeList_AirBag = contractGroupList.Where(c => c.TradeType == "气囊结构").Select(g => new TradeSingleDetailReport(g)).ToList(); tradeTypes.Remove("气囊结构"); report.CreatedModel.TradeList_PayoffSwap = contractGroupList.Where(c => c.TradeType == "收益互换").Select(g => new TradeSingleDetailReport(g)).ToList(); tradeTypes.Remove("收益互换"); report.CreatedModel.TradeList_Custom = contractGroupList.Where(c => c.TradeType == "自定义交易").Select(g => new TradeSingleDetailReport(g)).ToList(); var extendInfos = report.CreatedModel.TradeList_Custom.Where(x => x.TdDetail.ExtendInfo != null).Select(x => x.TdDetail).ToList(); var propertys = new List(); extendInfos.ForEach(x => { propertys.AddRange(x.Propertys); }); report.CreatedModel.PropertyNames_Custom = propertys.Select(x => x.name).Distinct().ToList(); tradeTypes.Remove("自定义交易"); report.CreatedModel.TradeList_SSpread = contractGroupList.Where(c => c.TradeType == "合成价差期权").Select(g => new TradeSingleDetailReport(g)).ToList(); tradeTypes.Remove("合成价差期权"); report.CreatedModel.TradeList_Enhance = contractGroupList.Where(c => c.TradeType == "收益增强结构").Select(g => new TradeSingleDetailReport(g)).ToList(); tradeTypes.Remove("收益增强结构"); report.CreatedModel.TradeList_Cashflow = contractGroupList.Where(c => c.TradeType == "现金流交易").Select(g => new TradeSingleDetailReport(g)).ToList(); tradeTypes.Remove("现金流交易"); var accumulatorOptionIds = DbContext.trade_accumulator_option.Where(l => l.AccumulatorStructureType == AccumulatorStructureTypeEnum.Segmented).Select(l => l.TradeId).ToList(); report.CreatedModel.TradeList_Accumulator = contractGroupList.Where(c => c.TradeType == "累计期权" && !accumulatorOptionIds.Contains(c.id)).Select(g => new TradeSingleDetailReport(g)).ToList(); report.CreatedModel.TradeList_AccumulatorSegmented = contractGroupList.Where(c => c.TradeType == "累计期权" && accumulatorOptionIds.Contains(c.id)).Select(g => new TradeSingleDetailReport(g)).ToList(); tradeTypes.Remove("累计期权"); report.CreatedModel.Tradelist_Risky = contractGroupList.Where(c => c.TradeType == "Risky期权").Select(g => new TradeSingleDetailReport(g)).ToList(); tradeTypes.Remove("Risky期权"); report.CreatedModel.TradeList_Others = contractGroupList.Where(c => tradeTypes.Contains(c.TradeType)).Select(g => new TradeSingleDetailReport(g)).ToList(); Func sumf = q => q.TradePrice; report.CreatedModel.VanillaTradePriceSum = report.CreatedTradeList_Vanilla.Sum(sumf); report.CreatedModel.AsianTradePriceSum = report.CreatedTradeList_Asian.Sum(sumf); report.CreatedModel.BinaryTradePriceSum = report.CreatedTradeList_Binary.Sum(sumf); report.CreatedModel.BarrierTradePriceSum = report.CreatedTradeList_Barrier.Sum(sumf); report.CreatedModel.DbSharkTradePriceSum = report.CreatedTradeList_DbShark.Sum(sumf); report.CreatedModel.AutocallTradePriceSum = report.CreatedTradeList_Autocall.Sum(sumf); report.CreatedModel.SnowballTradePriceSum = report.CreatedTradeList_Snowball.Sum(sumf); report.CreatedModel.RangeAccTradePriceSum = report.CreatedTradeList_RangeAcc.Sum(sumf); report.CreatedModel.AirBagTradePriceSum = report.CreatedTradeList_AirBag.Sum(sumf); report.CreatedModel.CustomTradePriceSum = report.CreatedTradeList_Custom.Sum(sumf); report.CreatedModel.SSpreadTradePriceSum = report.CreatedTradeList_SSpread.Sum(sumf); report.CreatedModel.CashflowTradePriceSum = report.CreatedTradeList_Cashflow.Sum(sumf); report.CreatedModel.AccumulatorTradePriceSum = report.CreatedTradeList_Accumulator.Sum(sumf); report.CreatedModel.RiskyTradePriceSum = report.CreatedTradeList_Risky.Sum(sumf); report.CreatedModel.AccumulatorTradeSegmentedPriceSum = report.CreatedTradeList_AccumulatorSegmented.Sum(sumf); contractGroupList = resultList.rows.Where(q => q.TcAction == ClientCashInCashOut.系统操作_平仓费 || (q.TcAction == ClientCashInCashOut.系统操作_行权费 && q.TcExerciseWay == TradeCashExerciseWayEnum.提前终止行权) || (q.TcExerciseWay != TradeCashExerciseWayEnum.到期行权 && q.IsLastAction)).ToList(); report.FinishedModel.TradePriceSum = contractGroupList.Sum(q => (q.TradePrice ?? 0) * ((q.BuySell == "买入" && q.TradeType != "远期") ? -1 : 1) * -1); report.FinishedModel.MinusAmountSum = contractGroupList.Sum(q => (q.TcAmount ?? 0) * -1); report.FinishedModel.WinLossSum = contractGroupList.Sum(q => (q.WinLoss ?? 0) * -1); report.FinishedModel.TradeList = contractGroupList.Select(g => new TradeSingleDetailReport(g)).ToList(); contractGroupList = resultList.rows.Where(q => (q.TcAction == ClientCashInCashOut.系统操作_行权费 || q.TcAction == ClientCashInCashOut.系统操作_互换) && q.TcExerciseWay == TradeCashExerciseWayEnum.到期行权).ToList(); report.MatureModel.TradePriceSum = contractGroupList.Sum(q => (q.TradePrice ?? 0) * ((q.BuySell == "买入" && q.TradeType != "远期") ? -1 : 1) * -1); report.MatureModel.MinusAmountSum = contractGroupList.Sum(q => (q.TcAmount ?? 0) * -1); report.MatureModel.WinLossSum = contractGroupList.Sum(q => (q.WinLoss ?? 0) * -1); report.MatureModel.TradeList = contractGroupList.Select(g => new TradeSingleDetailReport(g)).ToList(); report.ClientId = client.id; report.ClientName = client.Name; report.ClientFullName = client.Name; report.ClientNumber = client.Number; report.ClientAbbreviation = client.Abbreviation; report.CompanyName = PS.Config.CompanyFullName; report.ReportStart = req.StartDate == null ? DateTime.MinValue : req.StartDate.Value; report.ReportEnd = req.EndDate.Value; #region 处理表头表尾 var biaoTouList = Regex.Split(biaoTou, "

", RegexOptions.IgnoreCase).Where(x => !string.IsNullOrWhiteSpace(x)).ToList(); var newBiaoTouList = new List(); biaoTouList.ForEach(x => { x = Regex.Replace(x, "<[^>]+>", ""); x = Regex.Replace(x, "&[^;]+;", ""); newBiaoTouList.Add(x); }); report.BiaoTouLines = newBiaoTouList; report.BiaoTou = string.Join("\n", newBiaoTouList); var biaoWeiList = Regex.Split(biaoWei, "

", RegexOptions.IgnoreCase).Where(x => !string.IsNullOrWhiteSpace(x)).ToList(); var newBiaoWeiList = new List(); biaoWeiList.ForEach(x => { x = Regex.Replace(x, "<[^>]+>", ""); x = Regex.Replace(x, "&[^;]+;", ""); newBiaoWeiList.Add(x); }); report.BiaoWeiLines = newBiaoWeiList; report.BiaoWei = string.Join("\n", newBiaoWeiList); #endregion report.OutputFolder = req.OutputFolder; TradeDetailsReport = report; if (GenerateTradeDetails) { return GenerateTradeDetailsReportV2(report, client, req.fileType?.ToUpper() == "PDF", isCreateConfirmBookModeDirectory); } else { return ""; } } public List ExportReport(TradeDetailsReq req, string biaoTou = null, string biaoWei = null, bool isCreateConfirmBookModeDirectory = false) { var client = DataCacheProvider.GetClientDataSource().GetData(req.ClientId != 0 ? req.ClientId : req.ClientIdsInt[0]); if (client == null) { throw new ServiceException("系统中没有此客户,clientId:" + req.ClientId); } var files = new List(); var resultList = SearchTradeDetails(req); if (client.SupProtocolDate != null && resultList.rows.Where(x => (x.TcValueDate ?? x.TradeDate) > client.SupProtocolDate).Any() && resultList.rows.Where(x => (x.TcValueDate ?? x.TradeDate) < client.SupProtocolDate).Any()) { var req1 = req.Clone(); req1.EndDate = client.SupProtocolDate.Value.AddDays(-1); var resultList1 = SearchTradeDetails(req1); var file1 = ConfirmDanzhang(resultList1, client, req1, biaoTou, biaoWei, isCreateConfirmBookModeDirectory); files.Add(file1); var req2 = req.Clone(); req2.StartDate = client.SupProtocolDate; var resultList2 = SearchTradeDetails(req2); var file2 = ConfirmDanzhang(resultList2, client, req2, biaoTou, biaoWei, isCreateConfirmBookModeDirectory); files.Add(file2); } //发送邮件的时候邮件内容是所有交易,只是文件拆分 if (!files.Any()) { var file = ConfirmDanzhang(resultList, client, req, biaoTou, biaoWei, isCreateConfirmBookModeDirectory); files.Add(file); } else { ConfirmDanzhang(resultList, client, req, biaoTou, biaoWei, isCreateConfirmBookModeDirectory, false); } return files; } private string GenerateTradeDetailsReportV2(TradeDetailsReport report, Client client, bool needToPdf = false, bool isCreateConfirmBookModeDirectory = false) { //获取盯市报告模板信息 var templateFile = OtcAppContext.MapPath("~/App_Docs/导出模板/交易明细模板V2双章.xlsx"); var UseSingerBook = client.SupProtocolDate != null && (client.SupProtocolDate <= report.ReportStart || client.SupProtocolDate <= report.ReportEnd); if (UseSingerBook) { templateFile = OtcAppContext.MapPath("~/App_Docs/导出模板/交易明细模板V3单章.xlsx"); } var targetFolder = report.OutputFolder; if (string.IsNullOrEmpty(targetFolder)) { var date = report.ReportEnd; targetFolder = OtcAppContext.MapPath($"~/App_Docs/Download/{date:yyyyMM}/"); } if (isCreateConfirmBookModeDirectory) { if (UseSingerBook) { targetFolder = Path.Combine(targetFolder, "单章版"); } else { targetFolder = Path.Combine(targetFolder, "双章版"); } } string excelFileName; var startDate = report.ReportStart; if (startDate == DateTime.MinValue) { excelFileName = $"交易结算确认书_{report.ReportEnd:MMdd}_{report.ClientName}.xlsx"; } else { excelFileName = $"交易结算确认书_{startDate:MMdd}_{report.ReportEnd:MMdd}_{report.ClientName}.xlsx"; } var excelFilePath = Path.Combine(targetFolder, excelFileName); Directory.CreateDirectory(targetFolder); var dic = new Dictionary> { { "香草期权",report.CreatedTradeList_Vanilla}, { "合成价差期权",report.CreatedTradeList_SSpread}, { "亚式期权",report.CreatedTradeList_Asian}, { "二元期权",report.CreatedTradeList_Binary}, { "障碍期权",report.CreatedTradeList_Barrier}, { "双鲨期权",report.CreatedTradeList_DbShark}, { "凤凰",report.CreatedTradeList_Autocall}, { "雪球",report.CreatedTradeList_Snowball}, { "区间累积",report.CreatedTradeList_RangeAcc}, { "气囊结构",report.CreatedTradeList_AirBag}, { "收益增强结构",report.CreatedTradeList_Enhance}, { "现金流交易",report.CreatedTradeList_Cashflow}, { "累计期权",report.CreatedTradeList_Accumulator}, { "累计期权三段式",report.CreatedTradeList_AccumulatorSegmented}, { "自定义交易",report.CreatedTradeList_Custom}, { "远期",report.CreatedTradeList_Forward}, { "收益互换",report.CreatedTradeList_PayoffSwap}, { "Risky期权",report.CreatedTradeList_Risky}, { "提前终止",report.FinishedTradeList}, { "到期",report.MatureTradeList}, { "黑箱",report.CreatedTradeList_Others},//暂时取个名字 }; void generateExcelCallback(ExcelWorksheets sheets) { foreach (var sheet in sheets) { //删除空列表 if (sheet.Name == "交易明细") { var emptyRows = 0; var startRowIndex = 0; for (var i = 10; i < 100000 && emptyRows < 100; i++) { var str = sheet.GetValue(i, 1)?.ToString(); if (string.IsNullOrWhiteSpace(str)) { emptyRows++; } else { emptyRows = 0; if (str == "自定义交易") { if (dic.TryGetValue(str, out var em)) { if (!em.Any()) { sheet.DeleteRow(i, 4); i--; startRowIndex = i; } else { var titleColumnDic = new Dictionary(); var n = 1; foreach (var item in em) { n++; if (item.TdDetail.Propertys != null) { foreach (var property in item.TdDetail.Propertys) { if (titleColumnDic.ContainsKey(property.name)) { sheet.Cells[i + n, titleColumnDic[property.name]].Value = property.value; sheet.Cells[i + n, titleColumnDic[property.name]].Style.Font.Name = "微软雅黑"; sheet.Cells[i + n, titleColumnDic[property.name]].Style.Font.Size = 10; sheet.Cells[i + n, titleColumnDic[property.name]].Style.HorizontalAlignment = ExcelHorizontalAlignment.CenterContinuous; } else { sheet.Cells[i + 1, titleColumnDic.Count() + 15].Value = property.name; sheet.Cells[i + 1, titleColumnDic.Count() + 15].Style.Font.Bold = true; sheet.Cells[i + 1, titleColumnDic.Count() + 15].Style.Font.Name = "微软雅黑"; sheet.Cells[i + 1, titleColumnDic.Count() + 15].Style.Font.Size = 10; sheet.Cells[i + 1, titleColumnDic.Count() + 15].Style.HorizontalAlignment = ExcelHorizontalAlignment.CenterContinuous; sheet.Cells[i + n, titleColumnDic.Count() + 15].Value = property.value; sheet.Cells[i + n, titleColumnDic.Count() + 15].Style.Font.Name = "微软雅黑"; sheet.Cells[i + n, titleColumnDic.Count() + 15].Style.Font.Size = 10; sheet.Cells[i + n, titleColumnDic.Count() + 15].Style.HorizontalAlignment = ExcelHorizontalAlignment.CenterContinuous; titleColumnDic.Add(property.name, titleColumnDic.Count() + 15); } } } } startRowIndex = i + n + 2; } } if (report.CreatedTradeList_Others.Any()) { startRowIndex += 1; var positionCount = report.CreatedTradeList_Vanilla.Count() + report.CreatedTradeList_SSpread.Count() + report.CreatedTradeList_Asian.Count() + report.CreatedTradeList_Binary.Count() + report.CreatedTradeList_Barrier.Count() + report.CreatedTradeList_DbShark.Count() + report.CreatedTradeList_Autocall.Count() + report.CreatedTradeList_Snowball.Count() + report.CreatedTradeList_RangeAcc.Count() + report.CreatedTradeList_AirBag.Count() + report.CreatedTradeList_Enhance.Count() + report.CreatedTradeList_Cashflow.Count() + report.CreatedTradeList_Accumulator.Count() + report.CreatedTradeList_AccumulatorSegmented.Count() + report.CreatedTradeList_Custom.Count() + report.CreatedTradeList_Forward.Count() + report.CreatedTradeList_PayoffSwap.Count(); var tradeTypes = report.CreatedTradeList_Others.Select(x => x.TdDetail.TradeType).ToHashSet(); foreach (var tradeType in tradeTypes) { var eod_positionList_others = report.CreatedTradeList_Others.Where(x => x.TdDetail.TradeType == tradeType).ToList(); setPositionCell(sheet, startRowIndex, eod_positionList_others); startRowIndex += eod_positionList_others.Count + 4; } } else { dic.Remove("黑箱");//把暂时加的去掉 } } else { if (str == "成交") { var isEmpty = true; foreach (var item in dic) { if (item.Value.Count() > 0 && item.Key != "提前终止" && item.Key != "到期") { isEmpty = false; break; } } if (isEmpty) { sheet.DeleteRow(i, 1); i--; } } else if (dic.TryGetValue(str, out var em) && !em.Any()) { sheet.DeleteRow(i, 4); i--; } else if (dic.TryGetValue(str, out var em2) && em2.Any()) { i += em2.Count(); } } } } } } }; string text = FileHelper.ReplaceExtension(excelFilePath, ".pdf"); if (File.Exists(text)) { File.Delete(text); } var typeFileName = ExcelTemplate.GeneratePDFFromExeclTemplateV2(templateFile, excelFilePath, new Dictionary { { "交易明细", report } }, shouldDeleteSheet: true, needToPdf: needToPdf, callback: generateExcelCallback); return typeFileName; } private void setPositionCell(ExcelWorksheet sheet, int startRowIndex, List eod_positionList_others) { var defaultPosition = eod_positionList_others.FirstOrDefault(); sheet.InsertRow(startRowIndex, eod_positionList_others.Count() + 4); sheet.Cells[startRowIndex, 1].Value = defaultPosition.TdDetail.StructureType; sheet.Cells[startRowIndex, 1].Style.Font.Bold = true; sheet.Cells[startRowIndex, 1].Style.Font.Name = "微软雅黑"; sheet.Cells[startRowIndex, 1].Style.Font.Size = 10; sheet.Cells[startRowIndex, 1].Style.HorizontalAlignment = ExcelHorizontalAlignment.CenterContinuous; sheet.Cells[startRowIndex + 1, 1].Value = "交易编号"; sheet.Cells[startRowIndex + 1, 2].Value = "交易方向"; sheet.Cells[startRowIndex + 1, 3].Value = "交易日期"; sheet.Cells[startRowIndex + 1, 4].Value = "到期日期"; sheet.Cells[startRowIndex + 1, 5].Value = "交易总额"; sheet.Cells[startRowIndex + 1, 6].Value = "名义本金"; sheet.Cells[startRowIndex + 1, 7].Value = "标的代码"; sheet.Cells[startRowIndex + 1, 8].Value = "标的名称"; sheet.Cells[startRowIndex + 1, 9].Value = "期初价格"; for (var col = 1; col <= 9; col++) { sheet.Cells[startRowIndex + 1, col].Style.Font.Bold = true; sheet.Cells[startRowIndex + 1, col].Style.Font.Name = "微软雅黑"; sheet.Cells[startRowIndex + 1, col].Style.Font.Size = 10; sheet.Cells[startRowIndex + 1, col].Style.HorizontalAlignment = ExcelHorizontalAlignment.CenterContinuous; } var titleColumnDic = new Dictionary(); var j = 0; double totalTradePrice = 0; foreach (var item in eod_positionList_others) { j++; sheet.Cells[startRowIndex + 1 + j, 1].Value = item.TradeNumber; sheet.Cells[startRowIndex + 1 + j, 2].Value = item.BuySell; sheet.Cells[startRowIndex + 1 + j, 3].Value = item.TradeDate; sheet.Cells[startRowIndex + 1 + j, 4].Value = item.ExerciseDate; sheet.Cells[startRowIndex + 1 + j, 5].Value = item.TradePrice; sheet.Cells[startRowIndex + 1 + j, 6].Value = item.TdDetail.OriginalStockEqvNotional; sheet.Cells[startRowIndex + 1 + j, 7].Value = item.TdDetail.UnderlyingAssetName; sheet.Cells[startRowIndex + 1 + j, 8].Value = item.TdDetail.UnderlyingCode; sheet.Cells[startRowIndex + 1 + j, 9].Value = item.TdDetail.InitialSpotPrice; totalTradePrice += item.TradePrice; if (item.TdDetail.Propertys != null) { foreach (var property in item.TdDetail.Propertys) { if (titleColumnDic.ContainsKey(property.name)) { sheet.Cells[startRowIndex + j + 1, titleColumnDic[property.name]].Value = property.value; sheet.Cells[startRowIndex + j + 1, titleColumnDic[property.name]].Style.Font.Size = 10; sheet.Cells[startRowIndex + j + 1, titleColumnDic[property.name]].Style.Font.Name = "微软雅黑"; sheet.Cells[startRowIndex + j + 1, titleColumnDic[property.name]].Style.HorizontalAlignment = ExcelHorizontalAlignment.CenterContinuous; } else { sheet.Cells[startRowIndex + 1, titleColumnDic.Count() + 10].Value = property.name; sheet.Cells[startRowIndex + 1, titleColumnDic.Count() + 10].Style.Font.Bold = true; sheet.Cells[startRowIndex + 1, titleColumnDic.Count() + 10].Style.Font.Name = "微软雅黑"; sheet.Cells[startRowIndex + 1, titleColumnDic.Count() + 10].Style.Font.Size = 10; sheet.Cells[startRowIndex + 1, titleColumnDic.Count() + 10].Style.HorizontalAlignment = ExcelHorizontalAlignment.CenterContinuous; sheet.Cells[startRowIndex + j + 1, titleColumnDic.Count() + 10].Value = property.value; sheet.Cells[startRowIndex + j + 1, titleColumnDic.Count() + 10].Style.Font.Size = 10; sheet.Cells[startRowIndex + j + 1, titleColumnDic.Count() + 10].Style.Font.Name = "微软雅黑"; sheet.Cells[startRowIndex + j + 1, titleColumnDic.Count() + 10].Style.HorizontalAlignment = ExcelHorizontalAlignment.CenterContinuous; titleColumnDic.Add(property.name, titleColumnDic.Count() + 10); } } } for (var col = 1; col <= 9; col++) { sheet.Cells[startRowIndex + 1 + j, col].Style.Font.Size = 10; sheet.Cells[startRowIndex + 1 + j, col].Style.Font.Name = "微软雅黑"; sheet.Cells[startRowIndex + 1 + j, col].Style.HorizontalAlignment = ExcelHorizontalAlignment.CenterContinuous; } } sheet.Cells[startRowIndex + 1 + j + 2, 5].Value = totalTradePrice; sheet.Cells[startRowIndex + 1 + j + 2, 5].Style.Font.Size = 10; sheet.Cells[startRowIndex + 1 + j + 2, 5].Style.Font.Name = "微软雅黑"; sheet.Cells[startRowIndex + 1 + j + 2, 5].Style.Font.Bold = true; sheet.Cells[startRowIndex + 1 + j + 2, 5].Style.HorizontalAlignment = ExcelHorizontalAlignment.CenterContinuous; } private string GeneratePDFReport(string excelPath) { var tempFolder = OtcAppContext.MapPath("~/App_Docs/Temp"); if (!Directory.Exists(tempFolder)) { Directory.CreateDirectory(tempFolder); } var tempExcelFilePath = FileHelper.GetTargetFilePath(excelPath, tempFolder, true); File.Copy(excelPath, tempExcelFilePath); var pdfFilePath = FileHelper.ReplaceExtension(excelPath, ".pdf"); var excelfilepath2 = FileHelper.ReplaceExtension(excelPath, ".xlsx"); var wordfilepath = FileHelper.ReplaceExtension(excelPath, ".docx"); if (File.Exists(pdfFilePath)) { File.Delete(pdfFilePath); } if (File.Exists(excelfilepath2)) { OfficeFileConverter.ConvertFileFormat(excelfilepath2, pdfFilePath); } else { OfficeFileConverter.ConvertDocxToPDF(wordfilepath, pdfFilePath); } return pdfFilePath; } public SendTradeDetailReportResult SendTradeDetailReport(TradeDetailsReq req, TradeDetailsReport report, string luoKuan, List reportFilePath, string template, List receiver = null, List attachFiles = null, bool skip = false) { var AppendixType = DBCacheManager.Single.GetStr(CacheTable.TradeDerailsNeedAppendix, template); var filePathes = new List(); foreach (var item in reportFilePath) { var path = string.Empty; if (AppendixType == "PDF") { path = FileHelper.ReplaceExtension(item, ".pdf"); try { path = GeneratePDFReport(item); } catch (Exception ex) { throw new ServiceFaultException($"error:{ex.Message},file:{item}", ex); } } else { path = item; } filePathes.Add(path); } if (attachFiles != null && attachFiles.Count > 0) { //var allTradeNumbers = report.CreatedModel.TradeList.Select(o => o.TradeNumber) // .Concat(report.FinishedModel.TradeList.Select(o => o.TradeNumber)) // .Concat(report.MatureModel.TradeList.Select(o => o.TradeNumber)); //var allContractRCodes = DbContext.trade_contract_r.Where(o => o.IsValid && allTradeNumbers.Contains(o.TradeNumber)).Select(o => o.ContractCode); var documents = new List(); //var documentCodes = documents.Select(o => o.Code); //var contractr = DbContext.trade_contract_r.Where(o => o.IsValid && documentCodes.Contains(o.ContractCode)); var message = string.Empty; var clientIdsInt = new List(); if (!string.IsNullOrWhiteSpace(req.ClientIds)) { clientIdsInt.AddRange(req.ClientIdsInt); } else if (req.ClientId > 0) { clientIdsInt.Add(req.ClientId); } if (req.ParentFlag) { var clientIdList = DataCacheProvider.GetClientDataSource().AsQueryable(O => clientIdsInt.Contains(O.ParentId)).Select(O => O.id).ToList().ToHashSet(); clientIdsInt.AddRange(clientIdList); } if (attachFiles.Contains("交易确认书")) { var tradeNumbers = report.CreatedModel.TradeList.Select(o => o.TradeNumber); var ContractRs = DbContext.trade_contract_r.Where(o => o.IsValid && tradeNumbers.Contains(o.TradeNumber)).Select(o => o.ContractCode); var TempDocuments = DbContext.trade_contract_document.Where(o => attachFiles.Contains(o.Type) && ContractRs.Contains(o.Code) && clientIdsInt.Contains(o.ClientId ?? 0)).ToList(); ; documents.AddRange(TempDocuments); var documentCodes = documents.Select(o => o.Code); var contractr = DbContext.trade_contract_r.Where(o => o.IsValid && documentCodes.Contains(o.ContractCode)); var noDocsTrade = tradeNumbers.Concat(contractr.Select(o => o.TradeNumber)).Except(contractr.Select(o => o.TradeNumber)); if (noDocsTrade != null && noDocsTrade.Count() > 0) { message += string.Join(", ", noDocsTrade) + "未生成交易确认书!"; } } if (attachFiles.Contains("提前终止确认书")) { var tradeNumbers = report.FinishedModel.TradeList.Select(o => o.TradeNumber); var ContractRs = DbContext.trade_contract_r.Where(o => o.IsValid && tradeNumbers.Contains(o.TradeNumber)).Select(o => o.ContractCode); var TempDocuments = DbContext.trade_contract_document.Where(o => attachFiles.Contains(o.Type) && ContractRs.Contains(o.Code) && clientIdsInt.Contains(o.ClientId ?? 0)).ToList(); ; documents.AddRange(TempDocuments); var documentCodes = documents.Select(o => o.Code); var contractr = DbContext.trade_contract_r.Where(o => o.IsValid && documentCodes.Contains(o.ContractCode)); var noDocsTrade = tradeNumbers.Concat(contractr.Select(o => o.TradeNumber)).Except(contractr.Select(o => o.TradeNumber)); if (noDocsTrade != null && noDocsTrade.Count() > 0) { message += string.Join(", ", noDocsTrade) + "未生成提前终止确认书!"; } } if (attachFiles.Contains("结算确认书")) { var tradeNumbers = report.MatureModel.TradeList.Select(o => o.TradeNumber); var ContractRs = DbContext.trade_contract_r.Where(o => o.IsValid && tradeNumbers.Contains(o.TradeNumber)).Select(o => o.ContractCode); var TempDocuments = DbContext.trade_contract_document.Where(o => attachFiles.Contains(o.Type) && ContractRs.Contains(o.Code) && clientIdsInt.Contains(o.ClientId ?? 0)).ToList(); ; documents.AddRange(TempDocuments); var documentCodes = documents.Select(o => o.Code); var contractr = DbContext.trade_contract_r.Where(o => o.IsValid && documentCodes.Contains(o.ContractCode)); var noDocsTrade = tradeNumbers.Concat(contractr.Select(o => o.TradeNumber)).Except(contractr.Select(o => o.TradeNumber)); if (noDocsTrade != null && noDocsTrade.Count() > 0) { message += string.Join(", ", noDocsTrade) + "未生成结算确认书!"; } } if (!string.IsNullOrWhiteSpace(message) && !skip) { throw new Exception(message + "如需生成确认书请先取消(选择确认将发送含已生成文件的邮件,取消将结束发送邮件)!"); } var attchFilePathes = documents.Select(o => o.Paths) .ToHashSet(StringComparer.OrdinalIgnoreCase) .Select(mapPath => { if (!mapPath.StartsWith("/") && !mapPath.StartsWith("~/")) { mapPath = "/" + mapPath; } return OtcAppContext.MapPath(mapPath); }); filePathes.AddRange(attchFilePathes); } var clientContacts = new ClientDBContext().clientduty.Where(x => x.ApprovalOrder < 1 && x.ClientId == req.ClientId && (x.DeadLine == null || x.DeadLine > DateTime.Now) && x.IsReceiveEmail.HasValue && x.IsReceiveEmail == 1).ToList(); var clientContactMails = new List(); if (receiver != null && receiver.Count > 0) { foreach (var item in clientContacts) { var ids = item.ContactTypeId.Split(','); if (ids.Intersect(receiver).Count() != 0) { clientContactMails.Add(item.Email); } } } else { clientContactMails = clientContacts.Select(o => o.Email).ToList(); } var emails = DataConvert.EmailsSplitByComma(clientContactMails); // var attachFiles = new List { reportFilePath }; var startstr = req.StartDate.HasValue ? req.StartDate.Value.ToString("yyyy-MM-dd") : ""; var gh = req.StartDate.HasValue && req.EndDate.HasValue ? "-" : ""; var endstr = req.EndDate.HasValue ? req.EndDate.Value.ToString("yyyy-MM-dd") : ""; var endPart = (startstr == endstr) ? startstr : (startstr + gh + endstr); var title = $"【{PS.Config.Company}】{report.ClientName}-场外交易确认-{endPart}"; //邮件标题格式 "【当前公司】"+ 客户名称 + "-场外交易确认-" + 确认日期或区间 var status = EmailTradeConfirmResultType.Succeed; string sendMailMsg = null; var ccemail = DBCacheManager.Single.GetStr(CacheTable.CCEmail, template); var sendUser = DBCacheManager.Single.GetStr(CacheTable.TradeDetailsSendUser, template); if (emails.All(o => string.IsNullOrWhiteSpace(o))) { status = EmailTradeConfirmResultType.NoEmailSetting; } else { emails = emails.Where(o => !string.IsNullOrWhiteSpace(o)); if (!string.IsNullOrWhiteSpace(AppendixType)) { sendMailMsg = EmailHelper.SendMail(string.Join(";", emails), $"{report.ClientAbbreviation ?? ""}{title}", $"{luoKuan}", true, filePathes, ccemail, mailFrom: sendUser); } else { sendMailMsg = EmailHelper.SendMail(string.Join(";", emails), $"{report.ClientAbbreviation ?? ""}{title}", $"{luoKuan}", true, null, ccemail, mailFrom: sendUser); } if (!string.IsNullOrEmpty(sendMailMsg)) { status = EmailTradeConfirmResultType.EmailSentFailed; } } return new SendTradeDetailReportResult { ResultType = status, ErrorMsg = sendMailMsg }; } /// /// 根据交易编号获取otctradefull(组合标的名义本金在方法内做了转换) /// public OtcOptionTradeFull GetOtcTradeFull(string tradeNumber) { if (string.IsNullOrWhiteSpace(tradeNumber)) { return null; } var dbTrade = DbContext.trade.FirstOrDefault(n => n.TradeNumber == tradeNumber); return FromDbTrade(dbTrade); } /// /// 根据交易编号获取otctradefull(组合标的名义本金在方法内做了转换) /// public OtcOptionTradeFull GetOtcTradeFull(int id) { if (id < 1) { return null; } var dbTrade = DbContext.trade.FirstOrDefault(n => n.id == id); return FromDbTrade(dbTrade); } public OtcOptionTradeFull FromDbTrade(OtcTradeBase dbTrade, bool IsExtendFromDb = true) { if (dbTrade == null) { return null; } var otcTrade = new OtcOptionTradeFull(); YLAutoMapper.Map(dbTrade, otcTrade); if (IsExtendFromDb) { new TradeExtendService(this).SetTradeExtend(new[] { otcTrade }); } otcTrade.ClientNumber = ClientModule.ClientDataQueryService.GetClient(otcTrade.ClientId)?.Number; otcTrade.MetaDic = new TradeMetaService(this).GetTradeMeta(otcTrade.id); if (otcTrade.MetaDic.ContainsKey("MidVol") && double.TryParse(otcTrade.MetaDic["MidVol"], out var midvol)) { otcTrade.MidVol = midvol; } if (otcTrade.MetaDic.ContainsKey("Day1Pnl") && double.TryParse(otcTrade.MetaDic["Day1Pnl"], out var day1pnl)) { otcTrade.Day1Pnl = day1pnl; } if (otcTrade.MetaDic.ContainsKey("ExchangeRate") && double.TryParse(otcTrade.MetaDic["ExchangeRate"], out var exchangeRate)) { otcTrade.ExchangeRate = exchangeRate; } if (otcTrade.CountRatio == null || otcTrade.CountRatio.Value < 1) { otcTrade.CountRatio = DataCacheProvider.GetUnderlyingDataSource().GetData(otcTrade.UnderlyingCode)?.CountRatio ?? 1; } if (PS.Config.ErpElement.AccumulatorShowMultiplier1) { otcTrade.StrikeGearingFactor = otcTrade.OptionType == "看涨" ? otcTrade?.PutMultiplier : otcTrade?.CallMultiplier; } return otcTrade; } } /// /// 交易详情查询(根据客户) /// public class TradeDetailsReq : BaseSearchReq { /// /// 客户ID /// public int ClientId { get; set; } /// /// 客户ID列表 /// public string ClientIds { get; set; } public List ClientIdsInt { get { if (string.IsNullOrEmpty(ClientIds)) { return new List(); } return (ClientIds + "").Split(',').Select(c => Convert.ToInt32(c)).ToList(); } } /// /// 开始日期 /// public DateTime? StartDate { get; set; } /// /// 结束日期 /// public DateTime? EndDate { get; set; } /// /// 交易状态 /// public string DetailStatuses { get; set; } /// /// 交易类型 /// public List TradeTypes { get; set; } public string StructureType { get; set; } /// /// 批量下载结算报告/交易明细时,所在的文件夹路径 /// public string OutputFolder { get; set; } /// /// 用户关联的簿记账户(适用于有用户组的场景) /// public IEnumerable UserAssetUnits { get; set; } /// /// 分组TradeId /// public int GroupTradeId { get; set; } /// /// 文件类型 /// 仅支持pdf和xlsx /// public string fileType { get; set; } /// /// 是否包含子级账户 /// public bool ParentFlag { get; set; } public TradeDetailsReq Clone() { return (TradeDetailsReq)MemberwiseClone(); } } public class SendTradeDetailReportResult { public string ErrorMsg { get; set; } public EmailTradeConfirmResultType ResultType { get; set; } } }