Files
zszq-trs/YLErpDAL/Modules/ReportModule/UnwindReportService.cs
T

971 lines
48 KiB
C#

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
{
/// <summary>
/// 终止确认书服务
/// </summary>
public class UnwindReportService : YLBaseService
{
public UnwindReportService(OptUserInfo userInfo) : base(userInfo)
{
}
#region----来自客户平仓报告(已被删掉不用,这里的代码也等待删除)-----
/// <summary>
///
/// </summary>
public string SendEMailDayUnwindReport(int? ClientId, DateTime? OptDate, bool isShowAllTrades, List<int> userAssetBookIds)
{
var tradeStatusList = new List<string> { ConsTrade.已执行, ConsTrade.已平仓, ConsTrade.已到期 };
//获取所有客户信息
//List<Client> 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<string>();
var errorMsg = new List<string>();
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日") + "平仓报告成功。";
}
/// <summary>
///
/// </summary>
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<string> { 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<string> { 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
/// <summary>
/// 批量发送提前终止确认书
/// </summary>
public string SendEmailUnwindReport(TradeReq req)
{
//排除掉Broker
var predicate = PredicateBuilder.Create<Client>(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<trade_contract_document>();
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<EmailTemplate>(() => new EmailTemplateService(this).GetData("结算确认书"));
var stampTemplate = new Lazy<EmailTemplate>(() => new EmailTemplateService(this).GetData("结算确认书(用印)"));
Lazy<EmailTemplate> useTemplate;
var DateMsgs = new List<string>();
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<string>();
var successClients = new List<string>();
var errorMsg = new List<string>();
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<string>();
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 settlementRows = SettlementMailTemplateHelper.GetSettlementRows(DbContext, SettleBills, client.id);
var mailRequest = new MailInfoRequestModel
{
ClientName = client.Name,
TradeDate = valueDate.ToString("yyyy-MM-dd"),
DocNumber = SettleBills.Count > 0 ? SettleBills[0].Code : string.Empty
};
SettlementMailTemplateHelper.PopulateSettlementFields(mailRequest, settlementRows);
//组织邮件主体
var mailInfo = EmailTemplateService.GenerateMailInfo(useTemplate.Value, mailRequest) ?? 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}]提前终止报告成功。";
}
/// <summary>
/// 国君批量发送提前终止确认书
/// </summary>
public string GuojunSendEmailUnwindReport(TradeReq req)
{
//获取所有客户信息
//List<Client> 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<trade_contract_document>();
var trades = new List<trade>();
var trade_Cashes = new List<trade_cash>();
var instrumentTypeArr = new List<string>() { ConsGlobal.InstrumentType.Stock, ConsGlobal.InstrumentType.StockIF };
var getUnderlyingInstrumentType = new Func<int, string>((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<EmailTemplate>(() => new EmailTemplateService(this).GetData("结算确认书"));
var DateMsgs = new List<string>();
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<string>();
var successClients = new List<string>();
var errorMsg = new List<string>();
var clientListOn = ClientDataQueryService.GetClientsFromDB(PredicateBuilder.Create<Client>(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 = SettlementMailTemplateHelper.ForValueDate(
ts.Where(O => O.trade.ClientId == client.id), valueDate);
if (SettleBills.Count < 1)
{
continue;
}
var fileList = new List<string>();
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 mailRequest = new MailInfoRequestModel
{
ClientName = client.Name,
TradeDate = valueDate.ToString("yyyy-MM-dd"),
TradeList = sb.ToString(),
DocNumber = SettleBills.Count > 0 ? SettleBills[0].Code : string.Empty
};
SettlementMailTemplateHelper.PopulateSettlementFields(mailRequest, res);
//组织邮件主体
var mailInfo = EmailTemplateService.GenerateMailInfo(tempalte.Value, mailRequest) ?? 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<Datas> 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<string> instrumentTypeArr = new List<string>() { ConsGlobal.InstrumentType.Stock, ConsGlobal.InstrumentType.StockIF };
//if (!PS.Config.Is国泰君安 && !trades.Any(c => instrumentTypeArr.Contains(c.td.UnderlyingInstrumentType)))
//{
// return;
//}
sb.Append(@"<table style='text-align: center;' class='table-border' border='1'>
<thead style='background-color: #9D9D9D;'>
<tr class='firstRow'>
<td width = '90' valign='top'>交易编号</td>
<td width = '90' valign='top' >买方</td>
<td width = '90' valign='top'>交易达成日</td>
<td width = '90' valign ='top' >起始日- 到期日</td>
<td width = '90' valign ='top'>名义金额</td>
<td width = '90' valign ='top' >标的资产</td>
<td width = '90' valign ='top'>期权结构</td>
<td width = '90' valign ='top' >期初期权费</td>
<td width = '90' valign ='top'>结算日期</td>
<td width = '90' valign ='top'>结算价格</td>
<td width = '90' valign ='top'>结算规模</td>
<td width = '90' valign ='top'>结算单价</td>
<td width = '90' valign ='top'>结算期权费</td>
<td width = '90' valign ='top'>结算金额</td>
</tr>
</thead>");
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(@"<tbody><tr>
<td width = '90' valign = 'top'>{0}</td>
<td width = '90' valign = 'top'>{1}</td>
<td width = '90' valign = 'top'>{2}</td>
<td width = '90' valign = 'top'>{3}</td >
<td width = '90' valign = 'top'>{4}</td >
<td width = '90' valign = 'top'>{5}</td >
<td width = '90' valign = 'top'>{6}</td >
<td width = '90' valign = 'top'>{7}</td >
<td width = '90' valign = 'top'>{8}</td >
<td width = '90' valign = 'top'>{9}</td >
<td width = '90' valign = 'top'>{10}</td >
<td width = '90' valign = 'top'>{11}</td >
<td width = '90' valign = 'top'>{12}</td >
<td width = '90' valign = 'top'>{13}</td >
</tr>
</tbody>
", 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("</table>");
}
/// <summary>
/// 批量发送清算确认书和提前终止确认书
/// </summary>
public string SendEmailEitherReport(TradeReq req)
{
var types = new List<string>() { ContractTypeEnum.Clearing, ContractTypeEnum.UnWind };
//获取所有客户信息
//List<Client> 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<trade_contract_document>();
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<Client>(c => c.Name != PS.Config.CompanyFullName);
var tempalte = new Lazy<EmailTemplate>(() => new EmailTemplateService(this).GetData("结算确认书"));
var stampTemplate = new Lazy<EmailTemplate>(() => new EmailTemplateService(this).GetData("结算确认书(用印)"));
Lazy<EmailTemplate> useTemplate;
var DateMsgs = new List<string>();
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<string>();
var successClients = new List<string>();
var errorMsg = new List<string>();
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<string>();
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 settlementRows = SettlementMailTemplateHelper.GetSettlementRows(DbContext, SettleBills, client.id);
var mailRequest = new MailInfoRequestModel
{
ClientName = client.Name,
TradeDate = valueDate.ToString("yyyy-MM-dd"),
DocNumber = SettleBills.Count > 0 ? SettleBills[0].Code : string.Empty
};
SettlementMailTemplateHelper.PopulateSettlementFields(mailRequest, settlementRows);
//组织邮件主体
var mailInfo = EmailTemplateService.GenerateMailInfo(useTemplate.Value, mailRequest) ?? 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; }
}
}