971 lines
48 KiB
C#
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; }
|
|
}
|
|
}
|