679 lines
35 KiB
C#
679 lines
35 KiB
C#
using CsvHelper;
|
|
using Microsoft.AspNetCore.Http;
|
|
using NPOI.Util;
|
|
using Org.BouncyCastle.Ocsp;
|
|
using YLErp.DBModels;
|
|
using YLErp.DBModels.Consts;
|
|
using YLErp.Model.Enum;
|
|
using YLErp.Modules.ClientModule;
|
|
using YLErp.Modules.EodModule.QueryModule;
|
|
using YLErp.Modules.ReportModule;
|
|
using YLErp.Modules.TradeModule;
|
|
using YLErp.Office;
|
|
using YLErp.QdpModule;
|
|
using static iTextSharp.text.pdf.codec.TiffWriter;
|
|
using static NPOI.HSSF.Util.HSSFColor;
|
|
|
|
namespace YLErp.Web.Controllers
|
|
{
|
|
public class ClientPnlInfoController : BaseController
|
|
{
|
|
readonly IViewRenderService _viewRenderer;
|
|
|
|
public ClientPnlInfoController(IViewRenderService viewRenderer)
|
|
{
|
|
_viewRenderer = viewRenderer;
|
|
}
|
|
|
|
// GET: ClientPnlInfo
|
|
public ActionResult ClientPnlInfoList()
|
|
{
|
|
ViewBag.valueDate = valuedateBLL.ValueDate.ToString("yyyy-MM-dd");
|
|
return View();
|
|
}
|
|
|
|
public JsonResult GetClientPnlInfoList(ClientReq req)
|
|
{
|
|
var curUser = CurUser;
|
|
if (req.StartDate == null)
|
|
{
|
|
req.StartDate = valuedateBLL.SystemDate.AccruedTotalPnlStartDate ?? throw new ServiceException("请选择起始日期");
|
|
}
|
|
if (req.ValueDate == null)
|
|
{
|
|
req.ValueDate = valuedateBLL.ValueDate;
|
|
}
|
|
|
|
if (req.StartDate > req.ValueDate)
|
|
{
|
|
throw new ServiceException("结算开始日期不能大于结束日期!");
|
|
}
|
|
|
|
req.CurUserClientIds = CurUser.GetClientIdsByCurUser(true);
|
|
var clientService = new ClientQueryService(curUser);
|
|
var predicate = clientService.CreatePredicate(req,skipHavePosition:true);
|
|
var sList = clientService.SearchClientPnlInfoList(req, predicate);
|
|
|
|
var beforeStartDate = QdpCalendarHelper.GetNonHolidayDefore(req.StartDate.Value.AddDays(-1));
|
|
//if (req.StartDate.Value == req.ValueDate.Value)
|
|
//{
|
|
// req.StartDate = beforeStartDate;
|
|
//}
|
|
var lastEndDate = QdpCalendarHelper.GetNonHolidayDefore(req.ValueDate.Value);
|
|
//QdpCalendarHelper.GetNonHolidayDefore();
|
|
var clientIds = sList.rows.Select(a => a.id);
|
|
|
|
var lastEndDateBalanceList = yldb.ClientBalanceDaily.Where(a => clientIds.Contains(a.ClientId) && a.BalanceDate == lastEndDate)?.ToList();
|
|
var lastEndDateBalance = lastEndDateBalanceList.GroupBy(a => a.ClientId).ToDictionary(k => k.Key, v => v.FirstOrDefault());
|
|
|
|
var beforeStartDateBalanceList = yldb.ClientBalanceDaily.Where(a => clientIds.Contains(a.ClientId) && a.BalanceDate == beforeStartDate).ToList();
|
|
var beforeStartDateBalance = beforeStartDateBalanceList.GroupBy(a => a.ClientId).ToDictionary(k => k.Key, v => v.FirstOrDefault());
|
|
|
|
|
|
var clientIdList = sList.rows.Select(n => n.id).ToList();
|
|
var tradesList = yldb.trade.AsNoTracking().Where(n => clientIdList.Contains(n.ClientId) && n.ValidState != "InValid").ToList();
|
|
var tradeIds = tradesList.Select(n => n.id).ToList();
|
|
var tradeCashsList = yldb.trade_cash.AsNoTracking().Where(n => tradeIds.Contains(n.TradeId) && n.ValidState != "InValid" && (n.Action == "系统操作-平仓费" || n.Action == "系统操作-行权费")).ToList();
|
|
|
|
foreach (var x in sList.rows)
|
|
{
|
|
if (x.CustomerNature > 0)
|
|
{
|
|
x.CustomerNatureName = ((CustomerNatureEnum)x.CustomerNature.Value).ToString();
|
|
}
|
|
lastEndDateBalance.TryGetValue(x.id, out ClientBalanceDaily endDaily);
|
|
beforeStartDateBalance.TryGetValue(x.id, out ClientBalanceDaily beforeDaily);
|
|
|
|
x.PositionPnl = (endDaily?.PositionPnl ?? 0);
|
|
x.RoundedPositionPnl = (endDaily?.RoundedPositionPnl ?? 0);
|
|
x.WinLoss = (endDaily?.WinLossSum ?? 0) - (beforeDaily?.WinLossSum ?? 0);
|
|
|
|
x.PositionSumPnl = (endDaily?.PositionPnl ?? 0) + x.WinLoss - (beforeDaily?.PositionPnl ?? 0);
|
|
x.RoundedPositionSumPnl = (endDaily?.RoundedPositionPnl ?? 0) + x.WinLoss - (beforeDaily?.RoundedPositionPnl ?? 0);
|
|
|
|
|
|
//成交持仓
|
|
x.OpenPositionNum = tradesList.Count(n => n.ClientId == x.id && n.TradeStatus != "新增待确认" && n.TradeType != "收益互换" && (n.TradeType != "结构化交易" || n.IsGroup == 1) && n.IsGroup != 2 && n.StartDate >= req.StartDate && n.StartDate <= req.ValueDate);
|
|
//提前终止
|
|
var earlyTerminationNum = (from trade in tradesList
|
|
join tradeCash in tradeCashsList on trade.id equals tradeCash.TradeId
|
|
where trade.TradeType != "收益互换" && (trade.TradeType != "结构化交易" || trade.IsGroup == 1) && trade.IsGroup != 2 && tradeCash.ExerciseWay == "提前终止行权"
|
|
&& trade.ClientId == x.id && tradeCash.ValueDate >= req.StartDate && tradeCash.ValueDate <= req.ValueDate
|
|
select tradeCash).Count();
|
|
|
|
x.EarlyTerminationNum = earlyTerminationNum;
|
|
//到期
|
|
var dueToNum = (from trade in tradesList
|
|
join tradeCash in tradeCashsList on trade.id equals tradeCash.TradeId
|
|
where trade.TradeType != "收益互换" && (trade.TradeType != "结构化交易" || trade.IsGroup == 1) && trade.IsGroup != 2 && tradeCash.ExerciseWay == "到期行权"
|
|
&& trade.ClientId == x.id && tradeCash.ValueDate >= req.StartDate && tradeCash.ValueDate <= req.ValueDate
|
|
select tradeCash).Count();
|
|
x.DueToNum = dueToNum;
|
|
}
|
|
|
|
sList.Sum = SumHelper.CalculateSums(sList.rows);
|
|
|
|
return Json(sList);
|
|
}
|
|
|
|
public ActionResult ClientPnlInfoExport(ClientReq req)
|
|
{
|
|
object obj = null;
|
|
string targetFileName = null;
|
|
var sourceFileName = OtcAppContext.MapPath("~/App_Docs/导出模板/");
|
|
|
|
var temp = Path.Combine(sourceFileName, $"客户盈亏状况模板.xlsx");
|
|
sourceFileName = temp;
|
|
var searchList = GetClientPnlInfoList(req).Value as SearchListResult<ClientLinq>;
|
|
|
|
List<ClientPnlInfo> clientPnlInfos = new List<ClientPnlInfo>();
|
|
//模板绑定值,处理四舍五入配置
|
|
foreach (var c in searchList.rows)
|
|
{
|
|
if (PS.Config.IsPVRounded)
|
|
{
|
|
c.PositionPnl = c.RoundedPositionPnl;
|
|
c.PositionSumPnl = c.RoundedPositionSumPnl;
|
|
}
|
|
clientPnlInfos.Add(new ClientPnlInfo
|
|
{
|
|
Number = c.Number,
|
|
Name = c.Name,
|
|
CustomerManager = c.CustomerManager,
|
|
CustomerNature1 = c.CustomerNature1,
|
|
CustomerNature2 = c.CustomerNature2,
|
|
PositionPnl = c.PositionPnl.OtcFormat(OtcFormatFlag.tradePrice),
|
|
PositionSumPnl = c.PositionSumPnl.OtcFormat(OtcFormatFlag.tradePrice),
|
|
WinLoss = c.WinLoss.OtcFormat(OtcFormatFlag.tradePrice),
|
|
OpenPositionNum = c.OpenPositionNum,
|
|
EarlyTerminationNum = c.EarlyTerminationNum,
|
|
DueToNum = c.DueToNum,
|
|
});
|
|
}
|
|
|
|
var pairs = searchList.Sum as Dictionary<string, object>;
|
|
obj = new
|
|
{
|
|
WinLossSum = pairs["WinLossSum"],
|
|
PositionPnlSum = PS.Config.IsPVRounded ? Convert.ToDouble(pairs["RoundedPositionPnlSum"]).OtcFormat(OtcFormatFlag.tradePrice) : Convert.ToDouble(pairs["PositionPnlSum"]).OtcFormat(OtcFormatFlag.tradePrice),
|
|
PositionSumPnlSum = PS.Config.IsPVRounded ? Convert.ToDouble(pairs["RoundedPositionSumPnlSum"]).OtcFormat(OtcFormatFlag.tradePrice) : Convert.ToDouble(pairs["PositionSumPnlSum"]).OtcFormat(OtcFormatFlag.tradePrice),
|
|
InfoList = clientPnlInfos
|
|
};
|
|
|
|
targetFileName = $"客户盈亏状况模板_{req.ValueDate:yyyyMMdd}.xlsx";
|
|
if (obj == null) { throw new Exception("查询出错!"); }
|
|
var fileDownloadName = $"客户盈亏状况模板_{DateTime.Now:yyyyMMdd}.xlsx";
|
|
var modleDict = new Dictionary<string, object>
|
|
{
|
|
["Sheet1"] = obj
|
|
};
|
|
|
|
var result = OtcAppContext.GetExportFileOutputPath(targetFileName);
|
|
new ExcelTemplateGenerator().SetTemplateFile(sourceFileName).SetTemplateData(modleDict).OutputToFile(result.PhysicalPath);
|
|
|
|
return JsonSuccess("导出客户盈亏状况模板成功", result.WebPath);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 发送报告
|
|
/// </summary>
|
|
/// <param name="clientids"></param>
|
|
/// <param name="startdate"></param>
|
|
/// <param name="valuedate"></param>
|
|
/// <returns></returns>
|
|
public ActionResult ClientPnlInfoSend(string ClientIds, DateTime? StartDate, DateTime? ValueDate, bool HavePosition = false, bool HaveBanlance = false, bool HaveTrade = false)
|
|
{
|
|
ViewBag.ClientIds = ClientIds;
|
|
if (string.IsNullOrEmpty(ClientIds))
|
|
{
|
|
ViewBag.ClientCount = "全部客户";
|
|
}
|
|
else
|
|
{
|
|
var clientIdList = ClientIds.Split(',').Select(n => int.Parse(n)).ToList();
|
|
ViewBag.ClientCount = $"共计{clientIdList.Count}位客户";
|
|
}
|
|
|
|
|
|
var prewhereMode = "";
|
|
if (HaveTrade)
|
|
{
|
|
prewhereMode += "有交易;";
|
|
}
|
|
if (HavePosition)
|
|
{
|
|
prewhereMode += "有持仓;";
|
|
}
|
|
if (HaveBanlance)
|
|
{
|
|
prewhereMode += "有资金记录;";
|
|
}
|
|
|
|
ViewBag.PrewhereMode = string.IsNullOrEmpty(prewhereMode) ? "无" : prewhereMode.Substring(0, prewhereMode.Length - 1);
|
|
|
|
ViewBag.StartDate = StartDate?.ToString("yyyy-MM-dd");
|
|
ViewBag.ValueDate = (ValueDate == null ? valuedateBLL.ValueDate : ValueDate)?.ToString("yyyy-MM-dd");
|
|
ViewBag.HavePosition = HavePosition;
|
|
ViewBag.HaveBanlance = HaveBanlance;
|
|
ViewBag.HaveTrade = HaveTrade;
|
|
ViewBag.LuoKuanDesc = DBCacheManager.Single.GetStr(CacheTable.LuoKuanDesc);
|
|
ViewBag.MarginLuoKuanDesc = DBCacheManager.Single.GetStr(CacheTable.MarginLuoKuanDesc);
|
|
return View();
|
|
}
|
|
|
|
/// <summary>
|
|
/// 批量向客户发送报告
|
|
/// </summary>
|
|
/// <param name="input"></param>
|
|
/// <param name="detailTemplate"></param>
|
|
/// <param name="balanceTemplate"></param>
|
|
/// <param name="detailReceiver"></param>
|
|
/// <param name="balanceReceiver"></param>
|
|
/// <returns></returns>
|
|
[HttpPost]
|
|
public JsonResult BatchSendClientRiskMonitor(BatchSendClientRiskMonitorModel input, string detailTemplate, string balanceTemplate, List<string> detailReceiver = null, List<string> balanceReceiver = null)
|
|
{
|
|
input.Detail = Uri.UnescapeDataString(input.Detail ?? string.Empty);
|
|
input.MarginDetail = Uri.UnescapeDataString(input.MarginDetail ?? string.Empty);
|
|
switch (input.TradeDetailsDateType)
|
|
{
|
|
case "当日":
|
|
input.StartDate = input.ValueDate;
|
|
break;
|
|
case "当月区间":
|
|
input.StartDate = QdpCalendarHelper.GetNonHoliday(input.ValueDate.Date.AddDays(1 - input.ValueDate.Day));
|
|
break;
|
|
case "全部区间":
|
|
input.StartDate = DateTime.MinValue;
|
|
break;
|
|
}
|
|
var PrewhereModeClientIds = new List<int>();
|
|
var clientIds = new List<int>();
|
|
if (!string.IsNullOrEmpty(input.ClientIds))
|
|
{
|
|
clientIds = input.ClientIds.Split(',').Select(n => int.Parse(n)).ToList();
|
|
}
|
|
else
|
|
{
|
|
clientIds = clientDB.client.Where(n => n.ProcessStatus == "已开户").Select(n => n.id).ToList();
|
|
}
|
|
|
|
if (input.HaveTrade || input.HavePosition || input.HaveBanlance)
|
|
{
|
|
if (input.HaveTrade)
|
|
{
|
|
var hasTradeQuery = from tCash in yldb.trade_cash
|
|
join t in yldb.trade on tCash.TradeId equals t.id
|
|
where t.ValidState != "InValid" && t.TradeType != "收益互换" && (t.TradeType != "结构化交易" || t.IsGroup == 1) && t.IsGroup != 2
|
|
&& tCash.ValidState != "InValid" && tCash.ValueDate >= input.StartDate && tCash.ValueDate <= input.ValueDate && (tCash.Action != "系统操作-票息" || tCash.IsLastAction)
|
|
select t.ClientId;
|
|
|
|
PrewhereModeClientIds.AddRange(hasTradeQuery.ToList());
|
|
}
|
|
if (input.HavePosition)
|
|
{
|
|
PrewhereModeClientIds.AddRange(yldb.eod_trade_position.AsNoTracking().Where(n => n.ValueDate >= input.StartDate && n.ValueDate <= input.ValueDate && n.ClientId > 0 && n.TradeId > 0).Select(n => n.ClientId).ToList());
|
|
}
|
|
if (input.HaveBanlance)
|
|
{
|
|
var endDate = input.ValueDate.AddDays(1);
|
|
PrewhereModeClientIds.AddRange(yldb.ClientCashInCashOut.AsNoTracking().Where(n => n.HappenDate >= input.StartDate && n.HappenDate < endDate && n.ClientId > 0 && n.ValidState != "InValid").Select(n => n.ClientId.Value).ToList());
|
|
}
|
|
}
|
|
else
|
|
{
|
|
PrewhereModeClientIds.AddRange(yldb.trade.AsNoTracking().Where(n => n.StartDate >= input.StartDate && n.StartDate <= input.ValueDate && n.ValidState != "InValid" && n.TradeStatus == "确认成交" && n.TradeType != "收益互换" && (n.TradeType != "结构化交易" || n.IsGroup == 1) && n.IsGroup != 2).Select(n => n.ClientId).ToList());
|
|
PrewhereModeClientIds.AddRange(yldb.eod_trade_position.AsNoTracking().Where(n => n.ValueDate >= input.StartDate && n.ValueDate <= input.ValueDate && n.ClientId > 0 && n.TradeId > 0).Select(n => n.ClientId).ToList());
|
|
var endDate = input.ValueDate.AddDays(1);
|
|
PrewhereModeClientIds.AddRange(yldb.ClientCashInCashOut.AsNoTracking().Where(n => n.HappenDate >= input.StartDate && n.HappenDate < endDate && n.ClientId > 0 && n.ValidState != "InValid").Select(n => n.ClientId.Value).ToList());
|
|
PrewhereModeClientIds = PrewhereModeClientIds.Where(n => clientIds.Contains(n)).ToList();
|
|
}
|
|
if (PrewhereModeClientIds.Count == 0)
|
|
{
|
|
return JsonError($"所选客户{input.StartDate.ToString("yyyy-MM-dd")}-{input.ValueDate.ToString("yyyy-MM-dd")}区间内没有有交易、持仓、资金记录");
|
|
}
|
|
if (clientIds.Count > 0)
|
|
{
|
|
PrewhereModeClientIds = PrewhereModeClientIds.Where(n => clientIds.Contains(n)).ToList();
|
|
}
|
|
PrewhereModeClientIds = PrewhereModeClientIds.Distinct().ToList();
|
|
|
|
//区间内没有交易、持仓、资金记录的客户
|
|
var NoSendClientIds = clientIds.Where(n => !PrewhereModeClientIds.Contains(n)).ToList();
|
|
var noSemdClientNames = "";
|
|
if (NoSendClientIds.Count > 0)
|
|
{
|
|
var clientList = DataCacheProvider.GetClientDataSource().AsQueryable().ToList();
|
|
foreach (var noSendClientId in NoSendClientIds)
|
|
{
|
|
var noSendClient = clientList.FirstOrDefault(n => n.id == noSendClientId);
|
|
|
|
noSemdClientNames += noSendClient.Name + ";";
|
|
}
|
|
|
|
if (!string.IsNullOrEmpty(noSemdClientNames))
|
|
{
|
|
noSemdClientNames = noSemdClientNames.Substring(0, noSemdClientNames.Length - 1);
|
|
}
|
|
}
|
|
|
|
var clients = clientDB.client.Where(x => PrewhereModeClientIds.Contains(x.id))
|
|
.Select(n => new { n.id, n.Name }).ToArray()
|
|
.Select(n => new KeyValuePair<int, string>(n.id, n.Name)).ToArray();
|
|
IEnumerable<int> userAssetUnits = null;
|
|
if (ConsUserGroup.HasGroup && !ShowAllTrades)
|
|
{
|
|
userAssetUnits = GetUserAssetunitIds();
|
|
}
|
|
var port = Request.Host.Port;
|
|
var tradeListHtmlViewPath = Server.MapPath("~/Statics/views/TradeDetailsListMail.cshtml");
|
|
var extendParams = (input, CurUser, detailTemplate, balanceTemplate, userAssetUnits, tradeListHtmlViewPath, detailReceiver, balanceReceiver);
|
|
if (!ProgressHelper<KeyValuePair<int, string>>.Start(clients, "ClientBalanceReport", SendMailByClient, extendParams))
|
|
{
|
|
return JsonError("线程正在被占用");
|
|
}
|
|
|
|
var msg = "";
|
|
if (!string.IsNullOrEmpty(noSemdClientNames))
|
|
{
|
|
msg = $"以下客户:{noSemdClientNames}在{input.StartDate.ToString("yyyy-MM-dd")}-{input.ValueDate.ToString("yyyy-MM-dd")}区间内没有有交易、持仓、资金记录";
|
|
}
|
|
return JsonSuccess("开始发送邮件", new
|
|
{
|
|
resultMsg = msg,
|
|
isSend = 1
|
|
});
|
|
}
|
|
|
|
private string SendMailByClient(KeyValuePair<int, string> client, object extends)
|
|
{
|
|
var exParam = ((BatchSendClientRiskMonitorModel model, UserInfo CurUser, string detailTemplateName,
|
|
string balanceTemplateName, IEnumerable<int> userAssetUnits, string tradeListHtmlViewPath, List<string> detailReceiver, List<string> balanceReceiver))extends;
|
|
var clientName = client.Value;
|
|
var message = string.Empty;
|
|
var reqModel = exParam.model;
|
|
if (string.IsNullOrWhiteSpace(reqModel.Detail))
|
|
{
|
|
reqModel.Detail = DBCacheManager.Single.GetStr(CacheTable.LuoKuanDesc, exParam.balanceTemplateName);
|
|
reqModel.MarginDetail = DBCacheManager.Single.GetStr(CacheTable.MarginLuoKuanDesc, exParam.balanceTemplateName);
|
|
}
|
|
if (reqModel.HasTradeMarketReport)
|
|
{
|
|
try
|
|
{
|
|
var sheets = DBCacheManager.Single.GetStr(CacheTable.TradeMarketSheets, exParam.balanceTemplateName);
|
|
var ccEmail = DBCacheManager.Single.GetStr(CacheTable.MarketCCEmail, exParam.balanceTemplateName);
|
|
var emailData = new DingShiReportEmail()
|
|
{
|
|
ClientId = client.Key,
|
|
Detail = reqModel.Detail,
|
|
MarginDetail = reqModel.MarginDetail,
|
|
FileTypes = new List<DingShiReportEmail.CheckType>()
|
|
{
|
|
new DingShiReportEmail.CheckType()
|
|
{
|
|
type = "excel",
|
|
@checked = true
|
|
}
|
|
},
|
|
TargetFileType = "excel",
|
|
Title = reqModel.Title,
|
|
From = reqModel.StartDate,
|
|
To = reqModel.ValueDate,
|
|
CurUserName = exParam.CurUser.UserName,
|
|
SendContent = string.IsNullOrEmpty(sheets) ? new List<string>() { "账户状况", "持仓明细", "历史交易", "资金明细", "质押记录" } : sheets.Split(',').ToList(),
|
|
PayableFund = -1,//表示从后台获取
|
|
PayableMargin = -1,//表示从后台获取
|
|
ReportType = reqModel.ClientBalanceDataType,
|
|
CCEmail = ccEmail
|
|
};
|
|
try
|
|
{
|
|
var skipCheckMarginCall = DataCacheProvider.GetClientDataSource().AsQueryable().FirstOrDefault(x => x.id == client.Key)?.IsSendRecovery == 0;
|
|
var controller = new clientbalanceController(_viewRenderer)
|
|
{
|
|
reportUser = exParam.CurUser
|
|
};
|
|
var tradeMarketResult = controller.SendReportMails(emailData,
|
|
exParam.userAssetUnits, exParam.CurUser, exParam.balanceTemplateName, true, skipCheckMarginCall: skipCheckMarginCall, recevier: exParam.balanceReceiver).Result;
|
|
|
|
var data = tradeMarketResult.Value as Result;
|
|
if (!data.success)
|
|
{
|
|
message += "[客户" + clientName + "发送结算报告失败," + data.msg + "]; ";
|
|
}
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
LogFactory.GetLogger<clientbalanceController>().Error(e, "GenerateTradeMarketBill2");
|
|
message += "[客户" + clientName + "发送结算报告失败," + e.Message == "The number of columns in PdfPTable constructor must be greater than zero." ? "生成的pdf列表的列数必须大于零,请检查配置列不可为空" : e.Message + "]";
|
|
}
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
LogFactory.GetLogger<ClientController>().Error(e, "发送结算报告失败");
|
|
message += "[客户" + clientName + "发送结算报告失败," + e.Message + "]; ";
|
|
}
|
|
}
|
|
|
|
if (reqModel.HasTradeDetails)
|
|
{
|
|
try
|
|
{
|
|
var req = new TradeDetailsReq()
|
|
{
|
|
ClientId = client.Key,
|
|
StartDate = reqModel.StartDate,
|
|
EndDate = reqModel.ValueDate,
|
|
DetailStatuses = "成交,提前终止,到期"
|
|
};
|
|
var tradeDetailsResult = new tradeController().SendReportMails(req, exParam.CurUser, exParam.detailTemplateName, exParam.tradeListHtmlViewPath, exParam.detailReceiver).Result;
|
|
var data = tradeDetailsResult.Value as Result;
|
|
if (!data.success)
|
|
{
|
|
message += "[客户" + clientName + "发送交易明细失败," + data.msg + "]; ";
|
|
}
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
LogFactory.GetLogger<ClientController>().Error(e, "发送结算报告失败2");
|
|
var msg = e.InnerException != null ? e.InnerException.Message : e.Message;
|
|
message += "[客户" + clientName + "发送交易明细失败," + msg + "]; ";
|
|
}
|
|
}
|
|
return message;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 发送报告 下载
|
|
/// </summary>
|
|
/// <param name="input"></param>
|
|
/// <param name="detailTemplate"></param>
|
|
/// <param name="balanceTemplate"></param>
|
|
/// <param name="detailReceiver"></param>
|
|
/// <param name="balanceReceiver"></param>
|
|
/// <returns></returns>
|
|
public JsonResult BatchDownloadClientRiskMonitor(BatchSendClientRiskMonitorModel input, string balanceTemplate = "默认", string detailTemplate = "默认")
|
|
{
|
|
input.Detail = Uri.UnescapeDataString(input.Detail ?? string.Empty);
|
|
|
|
var startDate = input.StartDate;
|
|
var valueDate = input.ValueDate;
|
|
switch (input.TradeDetailsDateType)
|
|
{
|
|
case "当日":
|
|
startDate = input.ValueDate;
|
|
break;
|
|
case "当月区间":
|
|
startDate = QdpCalendarHelper.GetNonHoliday(input.ValueDate.Date.AddDays(1 - input.ValueDate.Day));
|
|
break;
|
|
case "全部区间":
|
|
startDate = DateTime.MinValue;
|
|
break;
|
|
}
|
|
var PrewhereModeClientIds = new List<int>();
|
|
var clientIds = new List<int>();
|
|
if (!string.IsNullOrEmpty(input.ClientIds))
|
|
{
|
|
clientIds = input.ClientIds.Split(',').Select(n => int.Parse(n)).ToList();
|
|
}
|
|
else
|
|
{
|
|
clientIds = clientDB.client.Where(n => n.ProcessStatus == "已开户").Select(n => n.id).ToList();
|
|
}
|
|
|
|
if (input.HaveTrade || input.HavePosition || input.HaveBanlance)
|
|
{
|
|
if (input.HaveTrade)
|
|
{
|
|
var hasTradeQuery = from tCash in yldb.trade_cash
|
|
join t in yldb.trade on tCash.TradeId equals t.id
|
|
where t.ValidState != "InValid" && t.TradeType != "收益互换" && (t.TradeType != "结构化交易" || t.IsGroup == 1) && t.IsGroup != 2
|
|
&& tCash.ValidState != "InValid" && tCash.ValueDate >= input.StartDate && tCash.ValueDate <= input.ValueDate && (tCash.Action != "系统操作-票息" || tCash.IsLastAction)
|
|
select t.ClientId;
|
|
|
|
PrewhereModeClientIds.AddRange(hasTradeQuery.ToList());
|
|
}
|
|
if (input.HavePosition)
|
|
{
|
|
PrewhereModeClientIds.AddRange(yldb.eod_trade_position.AsNoTracking().Where(n => n.ValueDate >= input.StartDate && n.ValueDate <= input.ValueDate && n.ClientId > 0 && n.TradeId > 0).Select(n => n.ClientId).ToList());
|
|
}
|
|
if (input.HaveBanlance)
|
|
{
|
|
var endDate = input.ValueDate.AddDays(1);
|
|
PrewhereModeClientIds.AddRange(yldb.ClientCashInCashOut.AsNoTracking().Where(n => n.HappenDate >= input.StartDate && n.HappenDate < endDate && n.ClientId > 0 && n.ValidState != "InValid").Select(n => n.ClientId.Value).ToList());
|
|
}
|
|
}
|
|
else
|
|
{
|
|
var hasTradeQuery = from tCash in yldb.trade_cash
|
|
join t in yldb.trade on tCash.TradeId equals t.id
|
|
where t.ValidState != "InValid" && t.TradeType != "收益互换" && (t.TradeType != "结构化交易" || t.IsGroup == 1) && t.IsGroup != 2
|
|
&& tCash.ValidState != "InValid" && tCash.ValueDate >= input.StartDate && tCash.ValueDate <= input.ValueDate && (tCash.Action != "系统操作-票息" || tCash.IsLastAction)
|
|
select t.ClientId;
|
|
PrewhereModeClientIds.AddRange(hasTradeQuery.ToList());
|
|
|
|
|
|
PrewhereModeClientIds.AddRange(yldb.eod_trade_position.AsNoTracking().Where(n => n.ValueDate >= input.StartDate && n.ValueDate <= input.ValueDate && n.ClientId > 0 && n.TradeId > 0).Select(n => n.ClientId).ToList());
|
|
|
|
var endDate = input.ValueDate.AddDays(1);
|
|
PrewhereModeClientIds.AddRange(yldb.ClientCashInCashOut.AsNoTracking().Where(n => n.HappenDate >= input.StartDate && n.HappenDate < endDate && n.ClientId > 0 && n.ValidState != "InValid").Select(n => n.ClientId.Value).ToList());
|
|
|
|
PrewhereModeClientIds = PrewhereModeClientIds.Where(n => clientIds.Contains(n)).ToList();
|
|
}
|
|
if (PrewhereModeClientIds.Count == 0)
|
|
{
|
|
throw new ServiceException($"所选客户{startDate.ToString("yyyy-MM-dd")}-{valueDate.ToString("yyyy-MM-dd")}区间内没有有交易、持仓、资金记录");
|
|
}
|
|
if (clientIds.Count > 0)
|
|
{
|
|
PrewhereModeClientIds = PrewhereModeClientIds.Where(n => clientIds.Contains(n)).ToList();
|
|
}
|
|
PrewhereModeClientIds = PrewhereModeClientIds.Distinct().ToList();
|
|
|
|
|
|
var clients = DataCacheProvider.GetClientDataSource().AsQueryable().ToList();
|
|
|
|
//区间内没有交易、持仓、资金记录的客户
|
|
var NoSendClientIds = clientIds.Where(n => !PrewhereModeClientIds.Contains(n)).ToList();
|
|
var noSemdClientNames = "";
|
|
if (NoSendClientIds.Count > 0)
|
|
{
|
|
var noClients = clients.Where(x => NoSendClientIds.Contains(x.id)).Select(n => n.Name).ToList();
|
|
foreach (var item in noClients)
|
|
{
|
|
noSemdClientNames += item + ";";
|
|
}
|
|
|
|
if (!string.IsNullOrEmpty(noSemdClientNames))
|
|
{
|
|
noSemdClientNames = noSemdClientNames.Substring(0, noSemdClientNames.Length - 1);
|
|
}
|
|
}
|
|
|
|
var clientList = clients.Where(x => PrewhereModeClientIds.Contains(x.id)).ToList();
|
|
var curUserName = CurUser.UserName;
|
|
var message = "";
|
|
var tempFolder = Server.MapPath("~/App_Docs/Temp");
|
|
var marketFolder = Path.Combine(tempFolder, "结算报告" + DateTime.Now.ToString("yyyyMMddHHmmss"));
|
|
var detailsFolder = Path.Combine(tempFolder, "交易明细" + DateTime.Now.ToString("yyyyMMddHHmmss"));
|
|
|
|
//如果没有相关数据,会创建一个空文件夹
|
|
Directory.CreateDirectory(marketFolder);
|
|
Directory.CreateDirectory(detailsFolder);
|
|
|
|
foreach (var clientId in PrewhereModeClientIds)
|
|
{
|
|
var client = clientList.FirstOrDefault(x => x.id == clientId);
|
|
if (client != null)
|
|
{
|
|
var clientName = client.Name;
|
|
|
|
if (input.HasTradeMarketReport)
|
|
{
|
|
try
|
|
{
|
|
var sheets = DBCacheManager.Single.GetStr(CacheTable.TradeMarketSheets, balanceTemplate);
|
|
var emailData = new DingShiReportEmail()
|
|
{
|
|
ClientId = clientId,
|
|
Detail = input.Detail,
|
|
FileTypes = new List<DingShiReportEmail.CheckType>()
|
|
{
|
|
new DingShiReportEmail.CheckType()
|
|
{
|
|
type = "excel",
|
|
@checked = true
|
|
}
|
|
},
|
|
TargetFileType = "excel",
|
|
Title = "结算报告",
|
|
From = startDate,
|
|
To = valueDate,
|
|
CurUserName = curUserName,
|
|
SendContent = string.IsNullOrEmpty(sheets) ? new List<string>() { "账户状况", "持仓明细", "历史交易", "资金明细", "质押记录" } : sheets.Split(',').ToList(),
|
|
PayableFund = -1,//表示从后台获取
|
|
PayableMargin = -1,//表示从后台获取
|
|
DownloadFilePath = marketFolder,
|
|
ReportType = input.ClientBalanceDataType
|
|
};
|
|
var controller = new clientbalanceController(_viewRenderer)
|
|
{
|
|
reportUser = CurUser
|
|
};
|
|
controller.GenerateDownloadTradeMarketBill2(emailData, balanceTemplate);
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
message += "[客户" + clientName + "生成结算报告失败," + e.Message + "]; ";
|
|
}
|
|
}
|
|
|
|
if (input.HasTradeDetails)
|
|
{
|
|
try
|
|
{
|
|
var req = new TradeDetailsReq()
|
|
{
|
|
ClientId = clientId,
|
|
StartDate = startDate,
|
|
EndDate = valueDate,
|
|
DetailStatuses = "成交,提前终止,到期",
|
|
OutputFolder = detailsFolder
|
|
};
|
|
var biaoTou = DBCacheManager.Single.GetStr(CacheTable.TradeDetailsBiaoTou, detailTemplate);
|
|
var biaoWei = DBCacheManager.Single.GetStr(CacheTable.TradeDetailsBiaoWei, detailTemplate);
|
|
var tradeDetailsService = new TradeDetailsQueryService(CurUser);
|
|
tradeDetailsService.ExportReport(req, biaoTou, biaoWei, true);
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
message += "[客户" + clientName + "生成交易明细失败," + e.Message + "]; ";
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
var marketZipFileName = "结算报告"
|
|
+ startDate.ToString("yyyyMMdd") + "-"
|
|
+ valueDate.ToString("yyyyMMdd")
|
|
+ ".zip";
|
|
var detailsZipFileName = "交易明细"
|
|
+ startDate.ToString("yyyyMMdd") + "-"
|
|
+ valueDate.ToString("yyyyMMdd")
|
|
+ ".zip";
|
|
|
|
var zipWebPath = $"/App_Docs/Temp/";
|
|
var zipLocalFolder = Server.MapPath(zipWebPath);
|
|
Directory.CreateDirectory(zipLocalFolder);
|
|
|
|
var marketZipFile = Path.Combine(zipLocalFolder, marketZipFileName);
|
|
var detailsZipFile = Path.Combine(zipLocalFolder, detailsZipFileName);
|
|
ZipHelper.ZipDirectory(marketFolder, marketZipFile);
|
|
ZipHelper.ZipDirectory(detailsFolder, detailsZipFile);
|
|
|
|
Directory.Delete(marketFolder, true);
|
|
Directory.Delete(detailsFolder, true);
|
|
|
|
if (!string.IsNullOrEmpty(message))
|
|
{
|
|
LogFactory.GetLogger("批量下载客户文件").Error(message);
|
|
}
|
|
|
|
|
|
var resultMsg = "";
|
|
|
|
if (!string.IsNullOrEmpty(noSemdClientNames))
|
|
{
|
|
resultMsg = $"以下客户:{noSemdClientNames}在{startDate.ToString("yyyy-MM-dd")}-{valueDate.ToString("yyyy-MM-dd")}区间内没有有交易、持仓、资金记录";
|
|
}
|
|
|
|
return JsonSuccess("批量下载成功", new
|
|
{
|
|
marketZipFile = zipWebPath + marketZipFileName,
|
|
detailsZipFile = zipWebPath + detailsZipFileName,
|
|
resultMsg = resultMsg
|
|
});
|
|
}
|
|
}
|
|
} |