using iTextSharp.text; using iTextSharp.text.pdf; using System.Text; using YLErp.BLL; using YLErp.Configuration; using YLErp.DBModels.Consts; using YLErp.DBModels.Converts; using YLErp.Helpers; using YLErp.Model; using YLErp.Model.Enum; using YLErp.Modules.AppModule; using YLErp.Modules.ClientModule; using YLErp.Office.iTextModule; using static Microsoft.EntityFrameworkCore.DbLoggerCategory; namespace YLErp.Modules.ReportModule { /// /// 终止确认书服务 /// public class UnwindReportService : YLBaseService { public UnwindReportService(OptUserInfo userInfo) : base(userInfo) { } #region----来自客户平仓报告(已被删掉不用,这里的代码也等待删除)----- /// /// /// public string SendEMailDayUnwindReport(int? ClientId, DateTime? OptDate, bool isShowAllTrades, List userAssetBookIds) { var tradeStatusList = new List { ConsTrade.已执行, ConsTrade.已平仓, ConsTrade.已到期 }; //获取所有客户信息 //List clientList = clientBLL.GetAllclientModel(); var systemDate = valuedateBLL.ValueDate; var bll = new tradeBLL(); //if (ClientId != null) //{ // req.ClientId = ClientId; // clientList = clientList.Where(t => t.id == (ClientId ?? 0)).ToList(); //} //if (clientList == null || clientList.Count == 0) //{ // throw new ServiceException("未找到用户信息!"); //} var req = new TradeReq { //req.TradeStatus = ConsTrade.确认成交; ClientId = ClientId, TradeStatusList = tradeStatusList, OptDateStart = OptDate.Value, OptDateEnd = OptDate.Value, sidx = "OptDate", sord = "desc" }; var tradeList = bll.SearchTradeList(req, true, true); if (tradeList != null && tradeList.Count > 0) { var tradeIds = tradeList.Select(t => t.id).ToList(); var tradeCash = DbContext.trade_cash.Where(t => tradeIds.Contains(t.TradeId) && !t.IsDeleted).ToList(); if (tradeCash != null && tradeCash.Count > 0) { tradeList.ForEach(t => { t.trade_cash = tradeCash.FirstOrDefault(a => a.TradeId == t.id); if (t.trade_cash != null) { t.trade_cash.Amount = t.trade_cash.Amount * (-1); } t.BuySell = ChangeBuySellToClient(t.BuySell); }); } } if (tradeList == null && tradeList.Count == 0) { throw new ServiceException(OptDate.Value.Date.ToString("yyyy年MM月dd日") + "没有可行权报告信息需要发送!"); } var clientIds = tradeList.Select(t => t.ClientId).ToList(); var clientListOn = clientIds.Count < 1 ? null : ClientDataQueryService.GetClientsFromDB(t => clientIds.Contains(t.id)).ToList(); if (clientListOn == null || clientListOn.Count < 1) { return "发送客户" + OptDate.Value.Date.ToString("yyyy年MM月dd日") + "平仓报告成功。"; } var errorClientList = new List(); var errorMsg = new List(); foreach (var client in clientListOn) { var filePath = GenerateUnwindReportFile(client.id, OptDate); // 要向该客户的所有订阅了邮件通知的人员发送邮件 var emails = ClientDataQueryService.GetClientEmails(client.id, false); if (!emails.Any()) { errorClientList.Add(client.Name); errorMsg.Add(client.Name + "用户没未设置可接受邮件人员信息"); continue; } var sendMail = EmailHelper.SendMail(string.Join(";", emails), "客户平仓报告-" + OptDate.Value.ToString("yyyy-MM-dd"), "", true, new[] { filePath }); if (!string.IsNullOrEmpty(sendMail)) { errorClientList.Add(client.Name); if (!errorMsg.Contains(sendMail)) { errorMsg.Add(sendMail); } } } //判断是否有发送失败的客户 if (errorClientList.Count > 0) { throw new ServiceException($"错误:{string.Join(",", errorClientList.ToArray())}发送报告时出错,{string.Join(",", errorMsg)}。"); } return "发送客户" + OptDate.Value.Date.ToString("yyyy年MM月dd日") + "平仓报告成功。"; } /// /// /// public string GenerateUnwindReportFile(int? clientId, DateTime? optDate) { var systemDate = valuedateBLL.ValueDate; var client = DataCacheProvider.GetClientDataSource().GetData(clientId ?? 0); var bll = new tradeBLL(); var req = new TradeReq { ClientId = clientId, //req.TradeStatus = ConsTrade.确认成交; TradeStatusList = new List { ConsTrade.已到期, ConsTrade.已执行, ConsTrade.已平仓 }, OptDateStart = optDate.Value, OptDateEnd = optDate.Value, sidx = "OptDate", sord = "desc" }; var tradeList = bll.SearchTradeList(req, true, true); if (tradeList != null && tradeList.Count > 0) { var tradeIds = tradeList.Select(t => t.id).ToList(); var tradeCash = DbContext.trade_cash.Where(t => tradeIds.Contains(t.TradeId) && !t.IsDeleted).ToList(); if (tradeCash != null && tradeCash.Count > 0) { tradeList.ForEach(t => { t.trade_cash = tradeCash.FirstOrDefault(a => a.TradeId == t.id); if (t.trade_cash != null) { t.trade_cash.Amount = t.trade_cash.Amount * (-1); } t.BuySell = ChangeBuySellToClient(t.BuySell); }); } } //设置文件名称 var saveFileDir = OtcAppContext.MapPath("~/App_Docs/DayUnwindReport"); if (!Directory.Exists(saveFileDir)) { Directory.CreateDirectory(saveFileDir); } var fileName = $"客户平仓报告-{optDate.Value:yyyy-MM-dd}-{client.Name}.pdf"; var filePath = Path.Combine(saveFileDir, fileName); var document = new Document(HeaderAndFooterEvent.rect); //此处使用的是http请求的流,你也可以使用文件流Stream var writer = PdfWriter.GetInstance(document, new FileStream(filePath, FileMode.Create)); try { document.Open(); writer.PageEvent = new HeaderAndFooterEvent(); HeaderAndFooterEvent.PAGE_NUMBER = true;//实现页眉跟页脚 HeaderAndFooterEvent.tpl = writer.DirectContent.CreateTemplate(1000, 1000); //定义模板 HeaderAndFooterEvent.HeaderLeft = ""; HeaderAndFooterEvent.HeaderRight = PS.Config.CompanyName ?? ""; //HeaderAndFooterEvent.FooterLeft = "TEL:010-87922095"; HeaderAndFooterEvent.FooterRight = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "(UTC)"; //每次在添加文本内容之前可以先设置字体,有效期持续到重新设置之前 HeaderAndFooterEvent.SetFont(BaseColor.DARK_GRAY, "宋体", 15, Font.BOLD); document.Add(HeaderAndFooterEvent.AddParagraph("客户平仓报告", 1, 1.5f)); HeaderAndFooterEvent.SetFont(BaseColor.DARK_GRAY, "宋体", 12); document.Add(HeaderAndFooterEvent.AddParagraph("客户: " + client.Name, 0, 1.5f)); document.Add(HeaderAndFooterEvent.AddParagraph("日期: " + optDate.Value.ToString("yyyy-MM-dd"), 0, 1.5f)); //增加空行 document.Add(HeaderAndFooterEvent.AddParagraph(" ", 0, 1.5f)); //输出客户客户平仓报告表格信息 var table = new PdfPTable(11); table.SetWidths(new float[] { 100, 200, 100, 150, 100, 130, 100, 100, 100, 100, 100 }); //table.HorizontalAlignment = Element.ALIGN_RIGHT; //table.SpacingBefore = (5); //table.SpacingAfter = (5); var bftitle = BaseFont.CreateFont("C:\\Windows\\Fonts\\SIMHEI.TTF", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED); //用系统中的字体文件SimHei.ttf创建文件字体 var fonttitle = new Font(bftitle, 8); var cellTexts = new string[] { "状态", "交易编号", "交易方向", "结构类型", "看涨看跌", "标的", "总份额", "平仓份额", "名义本金", "执行价格", "账本" }; foreach (var text in cellTexts) { var cell = new PdfPCell(new Phrase(text, fonttitle)) { BackgroundColor = (BaseColor.GRAY) }; table.AddCell(cell); } if (tradeList != null && tradeList.Count > 0) { var tradeStatusList = new List { ConsTrade.已执行, ConsTrade.已平仓, ConsTrade.已到期 }; foreach (var tradeStatus in tradeStatusList) { var tempTradeList = tradeList.Where(t => t.TradeStatus == tradeStatus).ToList(); if (tempTradeList == null || tempTradeList.Count == 0) { continue; } var cell = new PdfPCell(new Phrase(tradeStatus, fonttitle)) { Rowspan = (tempTradeList.Count), //cell.HorizontalAlignment = (Element.ALIGN_CENTER); VerticalAlignment = (Element.ALIGN_CENTER) }; table.AddCell(cell); foreach (var trade in tempTradeList) { table.AddCell(new Phrase(trade.TradeNumber, fonttitle)); table.AddCell(new Phrase(BuySellConvert.GetClientBuySell(trade.BuySell), fonttitle)); table.AddCell(new Phrase(trade.TradeType, fonttitle)); table.AddCell(new Phrase(trade.CallPut == "Call" ? "看涨" : "看跌", fonttitle)); table.AddCell(new Phrase(trade.UnderlyingCode, fonttitle)); table.AddCell(new Phrase(trade.Notional.ToString("###,##0.00"), fonttitle)); table.AddCell(new Phrase((trade.UnWindNotional ?? 0.0).ToString("###,##0.00"), fonttitle)); if (trade.StockEqvNotional == 0) { table.AddCell(new Phrase((trade.Notional * trade.SpotPrice) == null ? "0.0" : (trade.Notional * trade.SpotPrice).Value.ToString("###,##0.00"), fonttitle)); } else { table.AddCell(new Phrase((trade.StockEqvNotional).ToString("###,##0.00"), fonttitle)); } table.AddCell(new Phrase((trade.Strike) + "", fonttitle)); table.AddCell(new Phrase(trade.trade_cash == null ? "0.0" : trade.trade_cash.Amount.ToString("###,##0.00"), fonttitle)); } } } else { var cell = new PdfPCell(new Phrase("无", fonttitle)) { BackgroundColor = (BaseColor.YELLOW), HorizontalAlignment = (Element.ALIGN_CENTER), Colspan = (10) }; table.AddCell(cell); } table.DefaultCell.BackgroundColor = (null); document.Add(table); } finally { writer.Flush(); writer.CloseStream = true; document.Close(); } return filePath; } private string ChangeBuySellToClient(string BuySell) { return BuySell == "买入" ? "卖出" : "买入"; } #endregion /// /// 批量发送提前终止确认书 /// public string SendEmailUnwindReport(TradeReq req) { //排除掉Broker var predicate = PredicateBuilder.Create(c => c.Name != PS.Config.CompanyFullName); //检查实际终止日区间是否为空 if (!req.UnWindDateStart.HasValue || !req.UnWindDateEnd.HasValue) { throw new ServiceException($"发送提前终止确认书实际终止日期区间不得为空!"); } var contractQuery = DbContext.trade_contract_r.AsQueryable(); //获取当日所有清算确认书 var settleDocList = new List(); if (req.TradeCashIdList.Count > 0) { var tempSettleDocs = (from tcb in DbContext.trade_contract_document join tcr in contractQuery on tcb.Code equals tcr.ContractCode join tc in DbContext.trade_cash on tcr.TradeCashId equals tc.id where tcb.Type == ContractTypeEnum.UnWind && !tc.IsDeleted && req.TradeCashIdList.Contains(tc.id) && tcb.Type == tcr.Type && tcr.IsValid select new { tc.ValueDate, tcb }).ToList(); if (tempSettleDocs.Count == 0) { throw new ServiceException($"已勾选的提前终止确认书不存在!"); } tempSettleDocs.ForEach(O => { O.tcb.ValueDate = O.ValueDate; settleDocList.Add(O.tcb); }); } else { var tempSettleDocs = (from tcb in DbContext.trade_contract_document join tcr in contractQuery on tcb.Code equals tcr.ContractCode join tc in DbContext.trade_cash.Where(O => O.ValidState != ConsGlobal.InValid && !O.IsDeleted) on tcr.TradeCashId equals tc.id where tc.ValueDate >= req.UnWindDateStart.Value && tc.ValueDate <= req.UnWindDateEnd.Value && tcb.Type == ContractTypeEnum.UnWind && tcb.Type == tcr.Type && tcr.IsValid select new { tc.ValueDate, tcb }).ToList(); if (tempSettleDocs.Count == 0) { throw new ServiceException($"实际行权日区间:{req.UnWindDateStart.Value:yyyy-MM-dd}至{req.UnWindDateEnd.Value:yyyy-MM-dd},提前终止确认书已用印列表为空!"); } tempSettleDocs.ForEach(O => { O.tcb.ValueDate = O.ValueDate; settleDocList.Add(O.tcb); }); } if (req.SealResults != null) { if (req.SealResults.Contains(2)) { settleDocList = settleDocList.Where(t => req.SealResults.Contains((int)t.SealResult) || t.SealResult == null).ToList(); } else { settleDocList = settleDocList.Where(t => req.SealResults.Contains((int)t.SealResult)).ToList(); } } //#region 排除掉Broker //var baseName = AppSettingsConfig.BrokerClientName; //var baseClient = ClientDataProvider.GetClient(baseName); //if (baseClient != null) //{ // clientList = clientList.Where(c => c.id != baseClient.id).ToList(); //} //#endregion var tempalte = new Lazy(() => new EmailTemplateService(this).GetData("结算确认书")); var stampTemplate = new Lazy(() => new EmailTemplateService(this).GetData("结算确认书(用印)")); Lazy useTemplate; var DateMsgs = new List(); for (var valueDate = req.UnWindDateStart.Value; DateTime.Compare(req.UnWindDateEnd.Value, valueDate) >= 0; valueDate = valueDate.AddDays(1)) { var theDaySettleDocList = settleDocList.Where(t => t.ValueDate == valueDate).ToList(); //当日没有清算书 跳出 if (!theDaySettleDocList.Any()) { continue; } var buyerIds = theDaySettleDocList.Select(t => t.BuyerId ?? 0).Distinct().ToList(); var sellerIds = theDaySettleDocList.Select(t => t.SellerId ?? 0).Distinct().ToList(); var tempPredicate = predicate.And(t => buyerIds.Contains(t.id) || sellerIds.Contains(t.id)); var errorClients = new List(); var successClients = new List(); var errorMsg = new List(); var clientListOn = ClientDataQueryService.GetClientsFromDB(tempPredicate); foreach (var client in clientListOn) { useTemplate = tempalte; var SettleBills = theDaySettleDocList.Where(t => t.SellerId == client.id || t.BuyerId == client.id).ToList(); if (SettleBills.Count < 1) { continue; } var fileList = new List(); foreach (var docInfo in SettleBills) { if (PS.Config.ErpElement.ConfirmBookStampStatus) { //光子模式下如果用印文件存在则发送用印文件,否则发送原件; if (docInfo.AbsoluteStampPath.IsNullOrWhiteSpace()) { fileList.Add(Path.ChangeExtension(docInfo.AbsolutePath, "pdf")); } else { fileList.Add(docInfo.AbsoluteStampPath); if (!string.IsNullOrEmpty(stampTemplate?.Value?.BodyTemplate)) { useTemplate = stampTemplate; } } } else { fileList.Add(Path.ChangeExtension(docInfo.AbsolutePath, "pdf")); } } if (fileList.Count == 0) { continue; } //组织邮件主体 var mailInfo = EmailTemplateService.GenerateMailInfo(useTemplate.Value, new MailInfoRequestModel { ClientName = client.Name, TradeDate = valueDate.ToString("yyyy-MM-dd"), DocNumber = SettleBills.Count > 0 ? SettleBills[0].Code : string.Empty }) ?? new MailInfoResultModel { Body = string.Empty, Title = "清算确认书-" + valueDate.ToString("yyyy-MM-dd") }; // 要向该客户的所有订阅了邮件通知的人员发送邮件 var emails = ClientDataQueryService.GetClientEmails(client.id, false, req.receiver); if (emails == null || !emails.Any()) { errorClients.Add(client.Name); errorMsg.Add(client.Name + "用户没未设置可接受邮件人员信息"); continue; } var sendMail = EmailHelper.SendMail(string.Join(";", emails), mailInfo.Title, mailInfo.Body, mailInfo.IsBodyHtml, fileList.Distinct().ToArray()); if (!string.IsNullOrEmpty(sendMail)) { errorClients.Add(client.Name); if (!errorMsg.Contains(sendMail)) { errorMsg.Add(sendMail); continue; } } successClients.Add(client.Name); } var DateMsg = valueDate.ToString("yyyyMMdd") + ":"; if (successClients.Count > 0 || errorClients.Count > 0) { if (errorClients.Count > 0) { DateMsg += $"错误 -- {string.Join(",", errorClients.ToArray())}发送报告时出错,{string.Join(",", errorMsg.ToArray())}。"; } if (successClients.Count > 0) { DateMsg += $"成功 -- {string.Join(",", successClients.ToArray())}发送报告成功。"; } DateMsgs.Add(DateMsg); } } //判断是否有发送失败的客户 if (DateMsgs.Any(o => o.Contains("错误"))) { throw new ServiceException($"提示!{string.Join(",", DateMsgs.ToArray())}"); } if (req.TradeIdList.Count > 0) { throw new ServiceException($"已勾选的提前终止报告发送成功!"); } return $"发送客户[{req.UnWindDateStart.Value:yyyy-MM-dd}]至[{req.UnWindDateEnd.Value:yyyy-MM-dd}]提前终止报告成功。"; } /// /// 国君批量发送提前终止确认书 /// public string GuojunSendEmailUnwindReport(TradeReq req) { //获取所有客户信息 //List clientList = null; //if (string.IsNullOrWhiteSpace(req.ClientIds)) //{ // clientList = clientBLL.GetAllclientModel(); //} //else //{ // var ClientIdsList = req.ClientIds.Split(','); // clientList = clientBLL.GetAllclientModel().Where(t => ClientIdsList.Contains(t.id.ToString())).ToList(); //} //检查实际终止日区间是否为空 if (!req.UnWindDateStart.HasValue || !req.UnWindDateEnd.HasValue) { throw new ServiceException($"发送提前终止确认书实际终止日期区间不得为空!"); } //获取当日所有清算确认书 var settleDocList = new List(); var trades = new List(); var trade_Cashes = new List(); var instrumentTypeArr = new List() { ConsGlobal.InstrumentType.Stock, ConsGlobal.InstrumentType.StockIF }; var getUnderlyingInstrumentType = new Func((underlyingId) => { return DataCacheProvider.GetUnderlyingDataSource().GetData(underlyingId).UnderlyingInstrumentType; }); if (req.TradeCashIdList.Count > 0) { var tempSettleDocs = (from tcb in DbContext.trade_contract_document join tcr in DbContext.trade_contract_r on tcb.Code equals tcr.ContractCode join tc in DbContext.trade_cash on tcr.TradeCashId equals tc.id join t in DbContext.trade on tcr.TradeId equals t.id where tcb.Type == ContractTypeEnum.UnWind && !tc.IsDeleted && req.TradeCashIdList.Contains(tc.id) && tcb.Type == tcr.Type && tcr.IsValid select new { tc.ValueDate, tcb, t, tc }).ToList(); if (req.TradeCashIdList.Count != tempSettleDocs.Count) { throw new ServiceException($"请勾选已生成过确认书的交易!"); } tempSettleDocs.ForEach(O => { O.tcb.ValueDate = O.ValueDate; settleDocList.Add(O.tcb); trades.Add(O.t); trade_Cashes.Add(O.tc); }); } else { var tempSettleDocs = (from tcb in DbContext.trade_contract_document join tcr in DbContext.trade_contract_r on tcb.Code equals tcr.ContractCode join tc in DbContext.trade_cash.Where(O => O.ValidState != ConsGlobal.InValid && !O.IsDeleted) on tcr.TradeCashId equals tc.id join t in DbContext.trade on tcr.TradeId equals t.id where tc.ValueDate >= req.UnWindDateStart.Value && tc.ValueDate <= req.UnWindDateEnd.Value && tcb.Type == ContractTypeEnum.UnWind && tcb.Type == tcr.Type && tcr.IsValid select new { tc.ValueDate, tcb, t, tc }).ToList(); if (tempSettleDocs.Count == 0) { throw new ServiceException($"实际行权日区间:{req.UnWindDateStart.Value:yyyy-MM-dd}至{req.UnWindDateEnd.Value:yyyy-MM-dd},提前终止确认书已用印列表为空!"); } tempSettleDocs.ForEach(O => { O.tcb.ValueDate = O.ValueDate; settleDocList.Add(O.tcb); trades.Add(O.t); trade_Cashes.Add(O.tc); }); } //#region 排除掉Broker //var baseName = AppSettingsConfig.BrokerClientName; //var baseClient = ClientDataProvider.GetClient(baseName); //if (baseClient != null) //{ // clientList = clientList.Where(c => c.id != baseClient.id).ToList(); //} //#endregion var count = trades.GroupBy(O => new { UnderlyingInstrumentType = instrumentTypeArr.Contains(getUnderlyingInstrumentType(O.UnderlyingId)) ? 1 : 0 }).Count(); if (count > 1) { throw new ServiceException("不应勾选多个非股票(含股指期货)标的的交易"); } var tempalte = new Lazy(() => new EmailTemplateService(this).GetData("结算确认书")); var DateMsgs = new List(); for (var valueDate = req.UnWindDateStart.Value; DateTime.Compare(req.UnWindDateEnd.Value, valueDate) >= 0; valueDate = valueDate.AddDays(1)) { var theDaySettleDocList = settleDocList.Where(t => t.ValueDate == valueDate).ToList(); //当日没有清算书 跳出 if (!theDaySettleDocList.Any()) { continue; } var ts = (from t in trades join tc in trade_Cashes on t.id equals tc.TradeId select new Datas() { trade = t, tradecash = tc }).ToList(); var docClientIds = theDaySettleDocList.Select(t => t.BuyerId ?? 0).Distinct().ToList(); docClientIds.AddRange(theDaySettleDocList.Select(t => t.SellerId ?? 0).Distinct().ToList()); docClientIds = docClientIds.FindAll(O => O > 0); var errorClients = new List(); var successClients = new List(); var errorMsg = new List(); var clientListOn = ClientDataQueryService.GetClientsFromDB(PredicateBuilder.Create(t => t.Name != PS.Config.CompanyFullName && docClientIds.Contains(t.id))); foreach (var client in clientListOn) { var SettleBills = theDaySettleDocList.Where(t => t.SellerId == client.id || t.BuyerId == client.id).ToList(); var res = ts.Where(O => O.trade.ClientId == client.id).ToList(); if (SettleBills.Count < 1) { continue; } var fileList = new List(); foreach (var docInfo in SettleBills) { if (PS.Config.ErpElement.ConfirmBookStampStatus) { //光子模式下如果用印文件存在则发送用印文件,否则发送原件; if (docInfo.AbsoluteStampPath.IsNullOrWhiteSpace()) { fileList.Add(Path.ChangeExtension(docInfo.AbsolutePath, "pdf")); } else { fileList.Add(docInfo.AbsoluteStampPath); } } else { fileList.Add(Path.ChangeExtension(docInfo.AbsolutePath, "pdf")); } } if (fileList.Count == 0) { continue; } var sb = new StringBuilder(); SendEmailSettleBillHtml(sb, res); //组织邮件主体 var mailInfo = EmailTemplateService.GenerateMailInfo(tempalte.Value, new MailInfoRequestModel { ClientName = client.Name, TradeDate = valueDate.ToString("yyyy-MM-dd"), TradeList = sb.ToString(), DocNumber = SettleBills.Count > 0 ? SettleBills[0].Code : string.Empty }) ?? new MailInfoResultModel { Body = string.Empty, Title = "清算确认书-" + valueDate.ToString("yyyy-MM-dd") }; // 要向该客户的所有订阅了邮件通知的人员发送邮件 var emails = ClientDataQueryService.GetClientEmails(client.id, false, req.receiver); if (emails == null || !emails.Any()) { errorClients.Add(client.Name); errorMsg.Add(client.Name + "用户没未设置可接受邮件人员信息"); continue; } var sendMail = EmailHelper.SendMail(string.Join(";", emails), mailInfo.Title, mailInfo.Body, mailInfo.IsBodyHtml, fileList.Distinct().ToArray()); if (!string.IsNullOrEmpty(sendMail)) { errorClients.Add(client.Name); if (!errorMsg.Contains(sendMail)) { errorMsg.Add(sendMail); continue; } } successClients.Add(client.Name); } var DateMsg = valueDate.ToString("yyyyMMdd") + ":"; if (successClients.Count > 0 || errorClients.Count > 0) { if (errorClients.Count > 0) { DateMsg += $"错误 -- {string.Join(",", errorClients.ToArray())}发送报告时出错,{string.Join(",", errorMsg.ToArray())}。"; } if (successClients.Count > 0) { DateMsg += $"成功 -- {string.Join(",", successClients.ToArray())}发送报告成功。"; } DateMsgs.Add(DateMsg); } } //判断是否有发送失败的客户 if (DateMsgs.Any(o => o.Contains("错误"))) { throw new ServiceException($"提示!{string.Join(",", DateMsgs.ToArray())}"); } if (req.TradeIdList.Count > 0) { throw new ServiceException($"已勾选的提前终止报告发送成功!"); } return $"发送客户[{req.UnWindDateStart.Value:yyyy-MM-dd}]至[{req.UnWindDateEnd.Value:yyyy-MM-dd}]提前终止报告成功。"; } public void SendEmailSettleBillHtml(StringBuilder sb, List req) { //var trades = (from td in DbContext.trade // join tc in DbContext.trade_cash on td.id equals tc.TradeId // where req.TradeCashIdList.Contains(tc.id) // select new { tc.ValueDate, tc.FinalPrice, tc.UnwindPrice, tc.UnwindPricePercentRate, tc.UnwindPercentRate, tc.Amount, td }).ToList(); //List instrumentTypeArr = new List() { ConsGlobal.InstrumentType.Stock, ConsGlobal.InstrumentType.StockIF }; //if (!PS.Config.Is国泰君安 && !trades.Any(c => instrumentTypeArr.Contains(c.td.UnderlyingInstrumentType))) //{ // return; //} sb.Append(@""); foreach (var item in req) { var WinLoss = (item.tradecash.Amount + (item.trade.TradePrice ?? 0) * (item.tradecash.UnwindPercentRate ?? 0) * ((item.trade.BuySell == "卖出") ? 1 : -1)).OtcFormatMoney(); var settlementprice = (item.trade.IsUsePremiumRate != null && item.trade.IsUsePremiumRate.Value ? item.tradecash.UnwindPricePercentRate : item.tradecash.UnwindPrice); var buysell = item.trade.BuySell == "买入" ? "甲方" : "乙方"; var CountRatio = DataCacheProvider.GetUnderlyingDataSource().GetData(item.trade.UnderlyingId).CountRatio; sb.AppendFormat(@" ", item.trade.TradeNumber, buysell, item.trade.TradeDate.OtcFormatDate(), item.trade.StartDate.OtcFormatDate() + "-" + item.trade.ExerciseDate.OtcFormatDate(), item.trade.OriginalStockEqvNotional.OtcFormatMoney(), item.trade.UnderlyingCode, item.trade.TradeType, item.trade.TradePrice.OtcFormatMoney(), item.tradecash.ValueDate.OtcFormatDate(), item.tradecash.FinalPrice.OtcFormatMoney(), (item.tradecash.UnwindPercentRate * item.trade.OriginalNotional * CountRatio).OtcFormatMoney(), settlementprice.OtcFormatPercent(), item.tradecash.Amount.OtcFormatUmPrice(), WinLoss); } sb.Append("
交易编号 买方 交易达成日 起始日- 到期日 名义金额 标的资产 期权结构 期初期权费 结算日期 结算价格 结算规模 结算单价 结算期权费 结算金额
{0} {1} {2} {3} {4} {5} {6} {7} {8} {9} {10} {11} {12} {13}
"); } /// /// 批量发送清算确认书和提前终止确认书 /// public string SendEmailEitherReport(TradeReq req) { var types = new List() { ContractTypeEnum.Clearing, ContractTypeEnum.UnWind }; //获取所有客户信息 //List clientList = null; //if (string.IsNullOrWhiteSpace(req.ClientIds)) //{ // clientList = clientBLL.GetAllclientModel(); //} //else //{ // var ClientIdsList = req.ClientIds.Split(','); // clientList = clientBLL.GetAllclientModel().Where(t => ClientIdsList.Contains(t.id.ToString())).ToList(); //} //检查实际终止日区间是否为空 if (!req.UnWindDateStart.HasValue || !req.UnWindDateEnd.HasValue) { throw new ServiceException($"发送提前终止确认书实际终止日期区间不得为空!"); } var contractQuery = DbContext.trade_contract_r.AsQueryable(); //获取当日所有清算确认书 var settleDocList = new List(); if (req.TradeCashIdList.Count > 0) { var tempSettleDocs = (from tcb in DbContext.trade_contract_document join tcr in contractQuery on tcb.Code equals tcr.ContractCode join tc in DbContext.trade_cash on tcr.TradeCashId equals tc.id where types.Contains(tcb.Type) && !tc.IsDeleted && req.TradeCashIdList.Contains(tc.id) && tcb.Type == tcr.Type && tcr.IsValid select new { tc.ValueDate, tcb }).ToList(); if (req.TradeCashIdList.Count != tempSettleDocs.Count) { throw new ServiceException($"请勾选已生成过确认书的交易!"); } tempSettleDocs.ForEach(O => { O.tcb.ValueDate = O.ValueDate; settleDocList.Add(O.tcb); }); } else { var tempSettleDocs = (from tcb in DbContext.trade_contract_document join tcr in contractQuery on tcb.Code equals tcr.ContractCode join tc in DbContext.trade_cash.Where(O => O.ValidState != ConsGlobal.InValid && !O.IsDeleted) on tcr.TradeCashId equals tc.id where tc.ValueDate >= req.UnWindDateStart.Value && tc.ValueDate <= req.UnWindDateEnd.Value && types.Contains(tcb.Type) && tcb.Type == tcr.Type && tcr.IsValid select new { tc.ValueDate, tcb }).ToList(); if (tempSettleDocs.Count == 0) { throw new ServiceException($"实际行权日区间:{req.UnWindDateStart.Value:yyyy-MM-dd}至{req.UnWindDateEnd.Value:yyyy-MM-dd},提前终止确认书已用印列表为空!"); } tempSettleDocs.ForEach(O => { O.tcb.ValueDate = O.ValueDate; settleDocList.Add(O.tcb); }); } if (req.SealResults != null) { if (req.SealResults.Contains(2)) { settleDocList = settleDocList.Where(t => req.SealResults.Contains((int)t.SealResult) || t.SealResult == null).ToList(); } else { settleDocList = settleDocList.Where(t => req.SealResults.Contains((int)t.SealResult)).ToList(); } } //#region 排除掉Broker //var baseName = AppSettingsConfig.BrokerClientName; //var baseClient = DbContext.client.FirstOrDefault(t => baseName.Equals(t.Name)); //if (baseClient != null) //{ // clientList = clientList.Where(c => c.id != baseClient.id).ToList(); //} //#endregion //排除掉Broker var predicate = PredicateBuilder.Create(c => c.Name != PS.Config.CompanyFullName); var tempalte = new Lazy(() => new EmailTemplateService(this).GetData("结算确认书")); var stampTemplate = new Lazy(() => new EmailTemplateService(this).GetData("结算确认书(用印)")); Lazy useTemplate; var DateMsgs = new List(); for (var valueDate = req.UnWindDateStart.Value; DateTime.Compare(req.UnWindDateEnd.Value, valueDate) >= 0; valueDate = valueDate.AddDays(1)) { var theDaySettleDocList = settleDocList.Where(t => t.ValueDate == valueDate).ToList(); //当日没有清算书 跳出 if (!theDaySettleDocList.Any()) { continue; } var buyerIds = theDaySettleDocList.Select(t => t.BuyerId ?? 0).Distinct().ToList(); var sellerIds = theDaySettleDocList.Select(t => t.SellerId ?? 0).Distinct().ToList(); var errorClients = new List(); var successClients = new List(); var errorMsg = new List(); var tempPredicate = predicate.And(t => buyerIds.Contains(t.id) || sellerIds.Contains(t.id)); var clientListOn = ClientDataQueryService.GetClientsFromDB(tempPredicate); foreach (var client in clientListOn) { useTemplate = tempalte; var SettleBills = theDaySettleDocList.Where(t => t.SellerId == client.id || t.BuyerId == client.id).ToList(); if (SettleBills.Count < 1) { continue; } var fileList = new List(); foreach (var docInfo in SettleBills) { if (PS.Config.ErpElement.ConfirmBookStampStatus) { //光子模式下如果用印文件存在则发送用印文件,否则发送原件; if (docInfo.AbsoluteStampPath.IsNullOrWhiteSpace()) { fileList.Add(Path.ChangeExtension(docInfo.AbsolutePath, "pdf")); } else { fileList.Add(docInfo.AbsoluteStampPath); if (!string.IsNullOrEmpty(stampTemplate?.Value?.BodyTemplate)) { useTemplate = stampTemplate; } } } else { fileList.Add(Path.ChangeExtension(docInfo.AbsolutePath, "pdf")); } } if (fileList.Count == 0) { continue; } //组织邮件主体 var mailInfo = EmailTemplateService.GenerateMailInfo(useTemplate.Value, new MailInfoRequestModel { ClientName = client.Name, TradeDate = valueDate.ToString("yyyy-MM-dd"), DocNumber = SettleBills.Count > 0 ? SettleBills[0].Code : string.Empty }) ?? new MailInfoResultModel { Body = string.Empty, Title = "清算确认书-" + valueDate.ToString("yyyy-MM-dd") }; // 要向该客户的所有订阅了邮件通知的人员发送邮件 //var clientContactMails = DbContext.clientduty.Where(x => x.ClientId == client.id && x.IsReceiveEmail.HasValue && x.IsReceiveEmail == 1).Select(x => x.Email).ToList(); var emails = ClientDataQueryService.GetClientEmails(client.id, false, req.receiver); if (emails == null || !emails.Any()) { errorClients.Add(client.Name); errorMsg.Add(client.Name + "用户没未设置对应联系人类型下可接受邮件人员信息"); continue; } var sendMail = EmailHelper.SendMail(string.Join(";", emails), mailInfo.Title, mailInfo.Body, mailInfo.IsBodyHtml, fileList.Distinct().ToArray()); if (!string.IsNullOrEmpty(sendMail)) { errorClients.Add(client.Name); if (!errorMsg.Contains(sendMail)) { errorMsg.Add(sendMail); continue; } } successClients.Add(client.Name); } var DateMsg = valueDate.ToString("yyyyMMdd") + ":"; if (successClients.Count > 0 || errorClients.Count > 0) { if (successClients.Count > 0) { DateMsg += $"成功 -- {string.Join(",", successClients.ToArray())}发送报告成功。"; } if (errorClients.Count > 0) { DateMsg += $"错误 -- {string.Join(",", errorClients.ToArray())}发送报告时出错,{string.Join(",", errorMsg.ToArray())}。"; } DateMsgs.Add(DateMsg); } } if (DateMsgs.Any(o => o.Contains("错误"))) { throw new ServiceException($"提示!{string.Join(",", DateMsgs.ToArray())}"); } if (req.TradeIdList.Count > 0) { throw new ServiceException($"已勾选的提前终止报告发送成功!"); } return $"发送客户[{req.UnWindDateStart.Value:yyyy-MM-dd}]至[{req.UnWindDateEnd.Value:yyyy-MM-dd}]提前终止报告成功。"; } } public class Datas { public trade trade { get; set; } public trade_cash tradecash { get; set; } } }