using BaseOUDAL; using System.Collections.Concurrent; using YLErp.Configuration; using YLErp.DBModels.Consts; using YLErp.Model; using YLErp.Models; using YLErp.Modules.TradeDalModule; using YLErp.Modules.TradeModule.DocGenerateModule; namespace YLErp.Modules.TradeModule.DealModule { /// /// 交易确认书生成 /// public class TradeContractGenerateService : YLBaseService { public TradeContractGenerateService(YLBaseService baseService) : base(baseService) { } public TradeContractGenerateService(OptUserInfo userInfo) : base(userInfo) { } /// /// 确认书生成队列 /// private static readonly ConcurrentQueue<_ContractInfoModel> _ContractQueue = new ConcurrentQueue<_ContractInfoModel>(); /// /// 确认书缓存队列结构 /// private class _ContractInfoModel { public string ContractType; public List TradeIds; public _ContractInfoModel(string contractType, List tradeIds) { this.ContractType = contractType; this.TradeIds = tradeIds; } } /// /// 异步生成交易确认书 /// public void GenerateContractsAsync(List tradeIds, string contractType = "其它") { var status = false; lock (_ContractQueue) { status = _ContractQueue.IsEmpty; _ContractQueue.Enqueue(new _ContractInfoModel(contractType, tradeIds)); } if (status) { Task.Run(() => { while (!_ContractQueue.IsEmpty) { if (!_ContractQueue.TryPeek(out var obj)) { continue; } new TradeContractGenerateService(this).GenerateContracts(obj.TradeIds, obj.ContractType); lock (_ContractQueue) { _ContractQueue.TryDequeue(out _); } } }); } } /// /// 同步生成交易确认书 /// /// /// contractType为确认书的话,表示生成交易确认书;否则则生成提前终止确认书或者到期结算单 private TradeContractGenerateResultModel GenerateContracts(List tradeIds, string contractType = "其它") { ResetDbContext(); var result = new TradeContractGenerateResultModel(); try { if (contractType == "确认书") { result.ContractType = "确认书"; result.Success = GJGenerateConfirmBook(tradeIds, "PDF", out var errors, out _); result.Message = result.Success ? "生成确认书成功" : string.Join("\r\n", errors.AsEnumerable()); return result; } var clearingTradeIds = new List(); var unwindReportInputModels = new List(); var tcQuery = from tc in DbContext.trade_cash join t in DbContext.trade on tc.TradeId equals t.id where tradeIds.Contains(tc.TradeId) && !tc.IsDeleted select new { tc.id, tc.TradeId, tc.Action, tc.ExerciseWay, tc.IsLastAction, ValueDate = tc.HappenedDate ?? tc.ValueDate, t.ExerciseDate }; var lookUp = tcQuery.ToLookup(tc => tc.TradeId); var tradeCashes = lookUp.Select(l => l.OrderByDescending(m => m.id).First()).ToList(); foreach (var tc in tradeCashes) { if (tc.Action == ClientCashInCashOut.系统操作_平仓费 || (tc.Action == ClientCashInCashOut.系统操作_行权费 && tc.ExerciseWay == TradeCashExerciseWayEnum.提前终止行权)) { unwindReportInputModels.Add(new UnwindReportInputModel { TradeId = tc.TradeId, TradeCashId = tc.id }); } else if (tc.Action == ClientCashInCashOut.系统操作_行权费) { clearingTradeIds.Add(tc.TradeId); } else if (tc.Action == ClientCashInCashOut.系统操作_票息) { if (tc.ValueDate >= tc.ExerciseDate) { clearingTradeIds.Add(tc.TradeId); } else { unwindReportInputModels.Add(new UnwindReportInputModel { TradeId = tc.TradeId, TradeCashId = tc.id }); } } } var hasUnwindReport = unwindReportInputModels.Count > 0; if (hasUnwindReport) { result.ContractType = "提前终止确认书"; result.Success = GJGenerateUnwindReport(unwindReportInputModels, "PDF", out var errors, out _); result.Message = result.Success ? "生成提前终止确认书成功" : string.Join("\r\n", errors.AsEnumerable()); } if (clearingTradeIds.Count > 0) { result.ContractType = "到期结算单"; if (GJGenerateSettleBill(clearingTradeIds, "PDF", out var errors, out _)) { if (!hasUnwindReport) { result.Success = true; result.Message = "生成到期结算单成功"; } else if (result.Success) { result.Message = "生成到期结算单或提前终止确认书成功"; } } else if (result.Success) { result.Success = false; result.Message = string.Join("\r\n", errors.AsEnumerable()); } else { result.Message += (string.IsNullOrEmpty(result.Message) ? string.Empty : "\r\n") + string.Join("\r\n", errors.AsEnumerable()); } } return result; } catch (Exception ex) { result.Exception = ex; LogFactory.GetLogger("生成确认书").Error("确认书类型:" + result.ContractType, ex); } return result; } /// /// 生成交易确认书 /// public bool GJGenerateConfirmBook(List tradeIds, string docType, out IEnumerable errors, out IEnumerable files, DateTime? startDate = null, DateTime? endDate = null) { if (PS.Config.Company == CompanyEnum.国信金阳) { if (!GXJY_CorrespondingConfirmationTemplate(tradeIds, out string Msg)) { throw new ServiceException(Msg); } } Func getUnderlyingInstrumentType = new Func((underlyingId) => { return DataCacheProvider.GetUnderlyingDataSource().GetData(underlyingId)?.UnderlyingInstrumentType; }); List results = new List(); List error = new List(); List file = new List(); if (PS.Config.Is国泰君安 || PS.Config.Is厦门象屿) { var Tradelist = new TradeDalService(this).GetTradeOrEodTradeOfTidAPid(tradeIds, SystemValueDate, false, false); using (var basedb = new ErpBaseContext()) { if (Tradelist.Any(O => O.IsGroup > 0)) { int count = Tradelist.Where(O => O.IsGroup != 2).GroupBy(O => O.IsGroup).Count(); if (count > 1) { throw new ServiceException("不应勾选多个非黑盒标的的交易"); } var list = Tradelist.Where(x => x.TradeType == "结构化交易"); var group = list.GroupBy(O => new { O.ClientId, O.StructureType }).ToDictionary(K => K.Key, V => V.Select(O => O.id).ToList()); foreach (var item in group) { if (item.Key.StructureType == "折价") { var list2 = list.Where(x => item.Value.Contains(x.id) && x.TradeType == "结构化交易").ToList(); list2.ForEach(x => { var options = x.Propertys?.Where(o => o.name == "看涨看跌").ToList(); if (options != null && options.Any()) { x.ExtendOptionTypeInfo = JsonHelper.Serialize(options); } else { throw new ServiceException("看涨看跌不能为空:" + x.TradeNumber); } }); var group2 = list2.GroupBy(O => O.ExtendOptionTypeInfo).ToDictionary(K => K.Key, V => V.Select(O => O.id).ToList()); foreach (var item2 in group2) { groupGenerateHandle_Date(item2.Value, docType, startDate, endDate, results, error, file); if (error.Any()) break; } } else { groupGenerateHandle_Date(item.Value, docType, startDate, endDate, results, error, file); if (error.Any()) break; } } var swapList = Tradelist.Where(x => x.TradeType == "收益互换" && x.ParentTradeId == 0); foreach (var item in swapList) { groupGenerateHandle_Date(new List { item.id }, docType, startDate, endDate, results, error, file); } } } if (results.Count == 0) { var structTradeQuery = new TradeDalService(this).GetTradeOrEodTradeOfTidASid(tradeIds, SystemValueDate).Where(c => c.TradeType != "结构化交易"); List instrumentTypeArr = new List() { ConsGlobal.InstrumentType.Stock, ConsGlobal.InstrumentType.StockIndex, ConsGlobal.InstrumentType.StockIF }; DataCacheProvider.GetUnderlyingDataSource().AsQueryable(); if (structTradeQuery.Any(O => instrumentTypeArr.Contains(getUnderlyingInstrumentType(O.UnderlyingId)) || O.TradeType == "雪球期权")) { //暂时将所有子交易都作为判断依据,等拿到模板后再根据模板做调整更改; //目前是否为权益类的判断条件只是是否是股票,没有考虑IC IF等品种; int count = structTradeQuery.GroupBy(O => new { UnderlyingInstrumentType = (instrumentTypeArr.Contains(getUnderlyingInstrumentType(O.UnderlyingId)) || O.TradeType == "雪球期权") ? 1 : 0 }).Count(); if (count > 1) { throw new ServiceException("不应勾选多个非股票(含股指期货)标的的交易"); } var group = structTradeQuery.GroupBy(O => new { O.ClientId, O.TradeType }).ToDictionary(K => K.Key, V => V.Select(O => O.id).ToList()); foreach (var item in group) { if (item.Key.TradeType == "雪球期权") { if (structTradeQuery.Any(O => !instrumentTypeArr.Contains(getUnderlyingInstrumentType(O.UnderlyingId)))) { var group2 = DbContext.trade.Where(c => item.Value.Contains(c.id)).AsEnumerable().GroupBy(m => m.OptionType).ToDictionary(K => K.Key, V => V.Select(O => O.id).ToList()); foreach (var item2 in group2) { groupGenerateHandle_Date(item2.Value, docType, startDate, endDate, results, error, file); if (error.Any()) break; } } else { var group2 = DbContext.trade_snowball.Where(c => item.Value.Contains(c.TradeId)).AsEnumerable().GroupBy(m => m.IsFixedCoupon).ToDictionary(K => K.Key, V => V.Select(O => O.TradeId).ToList()); foreach (var item2 in group2) { if (item2.Key) { groupGenerateHandle_Date(item2.Value, docType, startDate, endDate, results, error, file); if (error.Any()) break; } else { var group3 = DbContext.trade.Where(c => item2.Value.Contains(c.id)).AsEnumerable().GroupBy(m => m.OptionType).ToDictionary(K => K.Key, V => V.Select(O => O.id).ToList()); foreach (var item3 in group3) { groupGenerateHandle_Date(item3.Value, docType, startDate, endDate, results, error, file); if (error.Any()) break; } } } } } else { groupGenerateHandle_Date(item.Value, docType, startDate, endDate, results, error, file); if (error.Any()) break; } } } } } else if (PS.Config.Is润和) { var TradeQuery = new TradeDalService(this).GetTradeOrEodTradeOfTidASid(tradeIds, SystemValueDate).Where(c => (c.TradeType != "结构化交易" || c.IsGroup == 1) && tradeIds.Contains(c.id)); if (TradeQuery.Any()) { var group = TradeQuery.GroupBy(O => new { O.ClientId, O.TradeDate }).ToDictionary(K => K.Key, V => V.Select(O => O.id).ToList()); foreach (var item in group) { var group2 = DbContext.trade.Where(c => item.Value.Contains(c.id) && c.TradeType == "远期").Select(O => O.id).ToList(); if (group2.Any()) { groupGenerateHandle(group2, docType, startDate, endDate, results, error, file); if (error.Any()) break; } var group4 = DbContext.trade.Where(c => item.Value.Contains(c.id) && c.TradeType == "亚式期权").Select(O => O.id).ToList(); if (group4.Any()) { groupGenerateHandle(group4, docType, startDate, endDate, results, error, file); if (error.Any()) break; } var group3 = DbContext.trade.Where(c => item.Value.Contains(c.id) && c.TradeType != "远期" && c.TradeType != "亚式期权").Select(O => O.id).ToList(); if (group3.Any()) { groupGenerateHandle(group3, docType, startDate, endDate, results, error, file); if (error.Any()) break; } } } } else if (PS.Config.Is东吴) { var TradeQuery = new TradeDalService(this).GetTradeOrEodTradeOfTidASid(tradeIds, SystemValueDate).Where(c => (c.TradeType != "结构化交易" || c.IsGroup == 1) && tradeIds.Contains(c.id)); if (TradeQuery.Any()) { var group = TradeQuery.GroupBy(O => new { O.ClientId, O.TradeDate }).ToDictionary(K => K.Key, V => V.Select(O => O.id).ToList()); foreach (var item in group) { var query = from t in DbContext.trade join tc in DbContext.trade_cash on t.id equals tc.TradeId where t.ClientId == item.Key.ClientId && tc.ValueDate == item.Key.TradeDate && !tc.IsDeleted && tc.Action == ClientCashInCashOut.系统操作_期权费 select new { t.id }; if (query.Any()) { groupGenerateHandle(query.Select(l => l.id).ToList(), docType, startDate, endDate, results, error, file); } } } } else if(PS.Config.Is物产中大) { var TradeQuery = new TradeDalService(this).GetTradeOrEodTradeOfTidASid(tradeIds, SystemValueDate).Where(c => (c.TradeType != "结构化交易" || c.IsGroup == 1) && tradeIds.Contains(c.id)); if (TradeQuery.Any()) { var group = TradeQuery.GroupBy(O => new { O.ClientId, O.TradeDate,O.TradeType }).ToDictionary(K => K.Key, V => V.Select(O => O.id).ToList()); foreach (var item in group) { if (item.Value.Count > 10) { throw new ServiceException("同客户同日期同类型交易生成超过限制!"); } var query = from t in DbContext.trade join tc in DbContext.trade_cash on t.id equals tc.TradeId where item.Value.Contains(tc.TradeId) && !tc.IsDeleted select new { t.id }; if (query.Any()) { groupGenerateHandle(query.Select(l => l.id).ToList(), docType, startDate, endDate, results, error, file); } } } } if (results.Count == 0) { results = new ConfirmationGenerateService(this).Generate(tradeIds, docType); } errors = results.Where(n => !string.IsNullOrWhiteSpace(n.ErrorMessage)).Select(n => n.ErrorMessage).ToList(); files = results.Where(n => !string.IsNullOrWhiteSpace(n.OutputFilePath)).Select(n => n.OutputFilePath).ToList(); return !errors.Any(); } private void groupGenerateHandle_Date(List ids, string docType, DateTime? startDate, DateTime? endDate, List results, List error, List file) { var trades = DbContext.trade.Where(c => ids.Contains(c.id)).ToList(); var supProtocolDate = DataCacheProvider.GetClientDataSource().GetData(trades.FirstOrDefault().ClientId).SupProtocolDate; var groupDateDouble = trades.Where(x => supProtocolDate == null || x.TradeDate < supProtocolDate).Select(x => x.id).ToList(); var groupDateSingle = trades.Where(x => supProtocolDate != null && x.TradeDate >= supProtocolDate).Select(x => x.id).ToList(); // 单章确认书和双章确认书同时生成要生成两个文件 if (groupDateDouble.Any() && groupDateSingle.Any()) { groupGenerateHandle(groupDateDouble, docType, startDate, supProtocolDate.Value.AddDays(-1), results, error, file); groupGenerateHandle(groupDateSingle, docType, supProtocolDate, endDate, results, error, file); } else if (groupDateDouble.Any()) { groupGenerateHandle(groupDateDouble, docType, startDate, endDate, results, error, file); } else if (groupDateSingle.Any()) { groupGenerateHandle(groupDateSingle, docType, startDate, endDate, results, error, file); } } private void groupGenerateHandle(List ids, string docType, DateTime? startDate, DateTime? endDate, List results, List error, List file) { var trade_contract_r = DbContext.trade_contract_r.Where(c => ids.Contains(c.TradeId) && c.Type == "交易确认书" && c.IsValid).ToList(); //DbContext.trade_contract_r.RemoveRange(trade_contract_r); trade_contract_r.ForEach(O => O.IsValid = false); DbContext.SaveChanges(); var result = new BatchConfirmationGenerateService(this).Generate(ids, docType, startDate, endDate); results.AddRange(result); error.AddRange(results.Where(n => !string.IsNullOrWhiteSpace(n.ErrorMessage)).Select(n => n.ErrorMessage).ToArray()); file.AddRange(results.Where(n => !string.IsNullOrWhiteSpace(n.OutputFilePath)).Select(n => n.OutputFilePath).ToList()); } public bool GXJY_CorrespondingConfirmationTemplate(List tradeIds, out string ErrMsg) { bool IsExist = true; ErrMsg = ""; var listTrade = DbContext.trade.Where(l => tradeIds.Contains(l.id)); foreach (var t in listTrade) { bool IsExistChild = false; var exerciseMode = t.ExerciseMode ?? ""; switch (t.TradeType) { case "亚式期权": IsExistChild = true; break; case "结构化交易": switch (t.StructureType) { case "普通亚式带保底": case "增强亚式": case "增强亚式价差": case "增强亚式价差组合标的": IsExistChild = true; break; } break; default: IsExistChild = true; break; } if (IsExistChild == false) { IsExist = false; ErrMsg += t.TradeNumber.ToString() + ","; } } if (!string.IsNullOrWhiteSpace(ErrMsg)) { ErrMsg = ErrMsg.Substring(0, ErrMsg.Length - 1); ErrMsg += "该交易没有相应确认书模板"; } return IsExist; } /// /// 生成提前中止确认书 /// public bool GJGenerateUnwindReport(List trades, string docType, out List errors, out List files) { var tdIds = trades.Select(t => t.TradeId).ToList(); if (PS.Config.Company == CompanyEnum.国信金阳) { var IsTradeContract = DbContext.trade_contract_r.Where(l => l.IsValid && tdIds.Contains(l.TradeId) && l.Type == "交易确认书").Select(l => l.TradeId).ToList(); var IsTradeIds = tdIds.Where(l => !IsTradeContract.Contains(l)).ToList(); if (IsTradeIds.Count > 0) { throw new ServiceException(String.Join(",", DbContext.trade.Where(l => IsTradeIds.Contains(l.id)).Select(l => l.TradeNumber).ToArray()) + "请生成该交易编号相应交易确认书"); } if (!GXJY_CorrespondingConfirmationTemplate(tdIds, out string Msg)) { throw new ServiceException(Msg); } } files = new List(); errors = new List(); if (PS.Config.Company == CompanyEnum.兴证) { IEnumerable results = null; results = new BatchUnwindReportGenerateService(this).Generate(trades, docType, UserId, UserName); errors = results.Where(n => !string.IsNullOrWhiteSpace(n.ErrorMessage)).Select(n => n.ErrorMessage).ToList(); files = results.Where(n => !string.IsNullOrWhiteSpace(n.OutputFilePath)).Select(n => n.OutputFilePath).ToList(); } else if (PS.Config.Company == CompanyEnum.海通) { var tradeCashIds = trades.Select(O => O.TradeCashId); var tradeCashStatus = new string[] { ClientCashInCashOut.系统操作_行权费, ClientCashInCashOut.系统操作_平仓费 }; var query = from t in DbContext.trade join tc in DbContext.trade_cash on t.id equals tc.TradeId where tradeCashIds.Contains(tc.id) && tc.ValidState != ConsGlobal.InValid && !tc.IsDeleted && tradeCashStatus.Contains(tc.Action) && tc.ExerciseWay == TradeCashExerciseWayEnum.提前终止行权 select new { t.id, tradeCashId = tc.id, t.ClientId }; var clientTradeDict = query.AsEnumerable().GroupBy(O => O.ClientId) .ToDictionary(K => K.Key, V => V.Select(O => new UnwindReportInputModel() { TradeId = O.id, TradeCashId = O.tradeCashId }).ToList()); foreach (var ctrades in clientTradeDict) { var results = new BatchUnwindReportGenerateService(this).Generate(ctrades.Value, "PDF", UserId, UserName); errors.AddRange(results.Where(n => !string.IsNullOrWhiteSpace(n.ErrorMessage)).Select(n => n.ErrorMessage).ToArray()); files.AddRange(results.Where(n => !string.IsNullOrWhiteSpace(n.OutputFilePath)).Select(n => n.OutputFilePath).ToList()); if (errors.Any()) break; } } else if (PS.Config.Is方顿) //同一笔交易结构化交易在一个确认书里 { List results = new List(); List error = new List(); List file = new List(); var tradeIds = trades.Select(O => O.TradeId).ToArray(); var query = DbContext.trade.Where(O => tradeIds.Contains(O.id)).Select(O => new { O.id, O.ParentTradeId }).ToList(); var group = query.GroupBy(O => O.ParentTradeId).ToDictionary(K => K.Key, V => V.Select(O => O.id).ToList()); foreach (var item in group) { if (item.Key == 0) { foreach (var item2 in item.Value) { var tradeCashIds = trades.Where(x => x.TradeId == item2).ToList(); var CashIds = trades.Where(x => x.TradeId == item2).Select(x => x.TradeId).ToList(); var trade_contract_r = DbContext.trade_contract_r.Where(c => CashIds.Contains(c.TradeCashId.Value) && c.IsValid).ToList(); trade_contract_r.ForEach(o => o.IsValid = false); DbContext.SaveChanges(); var result = new BatchUnwindReportGenerateService(this).Generate(tradeCashIds, docType, UserId, UserName); results.AddRange(result); error.AddRange(results.Where(n => !string.IsNullOrWhiteSpace(n.ErrorMessage)).Select(n => n.ErrorMessage).ToArray()); file.AddRange(results.Where(n => !string.IsNullOrWhiteSpace(n.OutputFilePath)).Select(n => n.OutputFilePath).ToList()); if (error.Any()) break; ; } } else { var tradeCashIds = (from t1 in item.Value join tc in trades on t1 equals tc.TradeId select tc).ToList(); var CashIds = (from t1 in item.Value join tc in trades on t1 equals tc.TradeId select tc.TradeId).ToList(); var trade_contract_r = DbContext.trade_contract_r.Where(c => CashIds.Contains(c.TradeCashId.Value) && c.IsValid).ToList(); trade_contract_r.ForEach(o => o.IsValid = false); DbContext.SaveChanges(); var result = new BatchUnwindReportGenerateService(this).Generate(tradeCashIds, docType, UserId, UserName); results.AddRange(result); error.AddRange(results.Where(n => !string.IsNullOrWhiteSpace(n.ErrorMessage)).Select(n => n.ErrorMessage).ToArray()); file.AddRange(results.Where(n => !string.IsNullOrWhiteSpace(n.OutputFilePath)).Select(n => n.OutputFilePath).ToList()); if (error.Any()) break; ; } } errors = results.Where(n => !string.IsNullOrWhiteSpace(n.ErrorMessage)).Select(n => n.ErrorMessage).ToList(); files = results.Where(n => !string.IsNullOrWhiteSpace(n.OutputFilePath)).Select(n => n.OutputFilePath).ToList(); } else { List results = new List(); if (PS.Config.Is国泰君安) { List error = new List(); List file = new List(); var tradeIds = trades.Select(O => O.TradeId); var tradecashId = trades.Select(o => o.TradeCashId).ToList(); Func getUnderlyingInstrumentType = new Func((underlyingId) => { return DataCacheProvider.GetUnderlyingDataSource().GetData(underlyingId).UnderlyingInstrumentType; }); List instrumentTypeArr = new List() { ConsGlobal.InstrumentType.Stock, ConsGlobal.InstrumentType.StockIF }; var query = DbContext.trade.Where(O => tradeIds.Contains(O.id)).Select(O => new { O.id, O.UnderlyingId, O.ClientId, O.TradeType }).ToList(); if (query.Any(O => instrumentTypeArr.Contains(getUnderlyingInstrumentType(O.UnderlyingId)) || O.TradeType == "雪球期权")) { //暂时将所有子交易都作为判断依据,等拿到模板后再根据模板做调整更改; //目前是否为权益类的判断条件只是是否是股票,没有考虑IC IF等品种; int count = query.GroupBy(O => new { UnderlyingInstrumentType = (instrumentTypeArr.Contains(getUnderlyingInstrumentType(O.UnderlyingId)) || O.TradeType == "雪球期权") ? 1 : 0 }).Count(); if (count > 1) { throw new ServiceException("不应勾选多个非股票(含股指期货)标的的交易"); } var group = query.GroupBy(O => new { O.ClientId }).ToDictionary(K => K.Key, V => V.Select(O => O.id).ToList()); foreach (var item in group) { var tradeCashIds = (from t1 in item.Value join tc in trades on t1 equals tc.TradeId select tc).ToList(); var CashIds = (from t1 in item.Value join tc in trades on t1 equals tc.TradeId select tc.TradeId).ToList(); var trade_contract_r = DbContext.trade_contract_r.Where(c => CashIds.Contains(c.TradeCashId.Value) && c.IsValid).ToList(); //DbContext.trade_contract_r.RemoveRange(trade_contract_r); trade_contract_r.ForEach(o => o.IsValid = false); DbContext.SaveChanges(); var result = new BatchUnwindReportGenerateService(this).Generate(tradeCashIds, docType, UserId, UserName); results.AddRange(result); error.AddRange(results.Where(n => !string.IsNullOrWhiteSpace(n.ErrorMessage)).Select(n => n.ErrorMessage).ToArray()); file.AddRange(results.Where(n => !string.IsNullOrWhiteSpace(n.OutputFilePath)).Select(n => n.OutputFilePath).ToList()); if (error.Any()) break; ; } } } if (results.Count == 0) { results = (List)new UnwindReportGenerateService(this).Generate(trades, docType); } errors = results.Where(n => !string.IsNullOrWhiteSpace(n.ErrorMessage)).Select(n => n.ErrorMessage).ToList(); files = results.Where(n => !string.IsNullOrWhiteSpace(n.OutputFilePath)).Select(n => n.OutputFilePath).ToList(); } return !errors.Any(); } /// /// 生成结算确认书 /// public bool GJGenerateSettleBill(List tradeIds, string docType, out IEnumerable errors, out IEnumerable files) { IEnumerable results; var settleSv = new SettlementBillGenerateService(this); results = settleSv.Generate(null, tradeIds, docType, UserId, UserName); errors = results.Where(n => !string.IsNullOrWhiteSpace(n.ErrorMessage)).Select(n => n.ErrorMessage).ToArray(); files = results.Where(n => !string.IsNullOrWhiteSpace(n.OutputFilePath)).Select(n => n.OutputFilePath).ToArray(); return !errors.Any(); } /// /// 根据传进来的合约代码过滤出已存在的合约代码 /// public IEnumerable GetExistsContractCode(IEnumerable contractCodes) { if (contractCodes == null) { throw new ArgumentNullException(nameof(contractCodes)); } if (!contractCodes.Any()) { return Enumerable.Empty(); } var query = (from a in DbContext.trade_contract_r.AsNoTracking() join b in DbContext.trade.AsNoTracking() on a.TradeId equals b.id where contractCodes.Contains(a.ContractCode) && b.ValidState != "InValid" && a.IsValid select a.ContractCode).Union (from tm in DbContext.TradeMeta.AsNoTracking() join t in DbContext.trade.AsNoTracking() on tm.TradeId equals t.id where (tm.MetaKey == ConsTradeMetaKey.ContractCode || tm.MetaKey.Contains("确认书")) && //伴星确认书编号的Key是合约编号,长江确认书编号的Key是日期+(交易确认书、结算确认书和提前终止确认书)+序号 t.ValidState != "InValid" && contractCodes.Contains(tm.MetaValue) select tm.MetaValue); //.Union //(from t in DbContext.trade.AsNoTracking() // where t.ValidState != "InValid" && contractCodes.Contains(t.TradeNumber) // select t.TradeNumber); return query.ToArray(); } } /// /// 交易确认书生成结果 /// public class TradeContractGenerateResultModel { public bool Success; public string Message; public string ContractType; public Exception Exception; } }