Files
zszq-trs/YLErpDAL/Modules/TradeModule/DealModule/TradeContractGenerateService.cs
T

794 lines
38 KiB
C#

using BaseOUDAL;
using DocumentFormat.OpenXml.Office.Word;
using System.Collections.Concurrent;
using System.Drawing.Printing;
using YLErp.Configuration;
using YLErp.DBModels.Consts;
using YLErp.Model;
using YLErp.Model.Enum;
using YLErp.Models;
using YLErp.Modules.TradeDalModule;
using YLErp.Modules.TradeModule.DocGenerateModule;
namespace YLErp.Modules.TradeModule.DealModule
{
/// <summary>
/// 交易确认书生成
/// </summary>
public class TradeContractGenerateService : YLBaseService
{
public TradeContractGenerateService(YLBaseService baseService) : base(baseService)
{
}
public TradeContractGenerateService(OptUserInfo userInfo) : base(userInfo)
{
}
/// <summary>
/// 确认书生成队列
/// </summary>
private static readonly ConcurrentQueue<_ContractInfoModel> _ContractQueue = new ConcurrentQueue<_ContractInfoModel>();
/// <summary>
/// 确认书缓存队列结构
/// </summary>
private class _ContractInfoModel
{
public string ContractType;
public List<int> TradeIds;
public _ContractInfoModel(string contractType, List<int> tradeIds)
{
this.ContractType = contractType;
this.TradeIds = tradeIds;
}
}
/// <summary>
/// 异步生成交易确认书
/// </summary>
public void GenerateContractsAsync(List<int> tradeIds, string contractType = "其它")
{
var status = false;
lock (_ContractQueue)
{
status = _ContractQueue.IsEmpty;
_ContractQueue.Enqueue(new _ContractInfoModel(contractType, tradeIds));
}
if (status)
{
Task.Run(() =>
{
while (!_ContractQueue.IsEmpty)
{
if (!_ContractQueue.TryPeek(out var obj))
{
continue;
}
new TradeContractGenerateService(this).GenerateContracts(obj.TradeIds, obj.ContractType);
lock (_ContractQueue)
{
_ContractQueue.TryDequeue(out _);
}
}
});
}
}
/// <summary>
/// 同步生成交易确认书
/// </summary>
/// <param name="tradeIds"></param>
/// <param name="contractType">contractType为确认书的话,表示生成交易确认书;否则则生成提前终止确认书或者到期结算单</param>
private TradeContractGenerateResultModel GenerateContracts(List<int> tradeIds, string contractType = "其它")
{
ResetDbContext();
var result = new TradeContractGenerateResultModel();
try
{
if (contractType == "确认书")
{
result.ContractType = "确认书";
result.Success = GJGenerateConfirmBook(tradeIds, "PDF", out var errors, out _);
result.Message = result.Success ? "生成确认书成功" : string.Join("\r\n", errors.AsEnumerable());
return result;
}
var clearingTradeIds = new List<int>();
var unwindReportInputModels = new List<UnwindReportInputModel>();
var tcQuery = from tc in DbContext.trade_cash
join t in DbContext.trade on tc.TradeId equals t.id
where tradeIds.Contains(tc.TradeId) && !tc.IsDeleted
select new
{
tc.id,
tc.TradeId,
tc.Action,
tc.ExerciseWay,
tc.IsLastAction,
ValueDate = tc.HappenedDate ?? tc.ValueDate,
t.ExerciseDate
};
var lookUp = tcQuery.ToLookup(tc => tc.TradeId);
var tradeCashes = lookUp.Select(l => l.OrderByDescending(m => m.id).First()).ToList();
foreach (var tc in tradeCashes)
{
if (tc.Action == ClientCashInCashOut.系统操作_平仓费 ||
(tc.Action == ClientCashInCashOut.系统操作_行权费 && tc.ExerciseWay == TradeCashExerciseWayEnum.提前终止行权))
{
unwindReportInputModels.Add(new UnwindReportInputModel { TradeId = tc.TradeId, TradeCashId = tc.id });
}
else if (tc.Action == ClientCashInCashOut.系统操作_行权费)
{
clearingTradeIds.Add(tc.TradeId);
}
else if (tc.Action == ClientCashInCashOut.系统操作_票息)
{
if (tc.ValueDate >= tc.ExerciseDate)
{
clearingTradeIds.Add(tc.TradeId);
}
else
{
unwindReportInputModels.Add(new UnwindReportInputModel { TradeId = tc.TradeId, TradeCashId = tc.id });
}
}
}
var hasUnwindReport = unwindReportInputModels.Count > 0;
if (hasUnwindReport)
{
result.ContractType = "提前终止确认书";
result.Success = GJGenerateUnwindReport(unwindReportInputModels, "PDF", out var errors, out _);
result.Message = result.Success ? "生成提前终止确认书成功" : string.Join("\r\n", errors.AsEnumerable());
}
if (clearingTradeIds.Count > 0)
{
result.ContractType = "到期结算单";
if (GJGenerateSettleBill(clearingTradeIds, "PDF", out var errors, out _))
{
if (!hasUnwindReport)
{
result.Success = true;
result.Message = "生成到期结算单成功";
}
else if (result.Success)
{
result.Message = "生成到期结算单或提前终止确认书成功";
}
}
else if (result.Success)
{
result.Success = false;
result.Message = string.Join("\r\n", errors.AsEnumerable());
}
else
{
result.Message += (string.IsNullOrEmpty(result.Message) ? string.Empty : "\r\n") + string.Join("\r\n", errors.AsEnumerable());
}
}
return result;
}
catch (Exception ex)
{
result.Exception = ex;
LogFactory.GetLogger("生成确认书").Error("确认书类型:" + result.ContractType, ex);
}
return result;
}
/// <summary>
/// 生成交易确认书
/// </summary>
public bool GJGenerateConfirmBook(List<int> tradeIds, string docType,
out IEnumerable<string> errors, out IEnumerable<string> files, DateTime? startDate = null, DateTime? endDate = null)
{
var logger = LogFactory.GetLogger("生成确认书");
logger.Info($"[GJGenerateConfirmBook] 开始生成确认书 - tradeIds.Count: {tradeIds?.Count ?? 0}, docType: {docType}, startDate: {startDate}, endDate: {endDate}");
Func<int, string> getUnderlyingInstrumentType = new Func<int, string>((underlyingId) =>
{
return DataCacheProvider.GetUnderlyingDataSource().GetData(underlyingId)?.UnderlyingInstrumentType;
});
List<TradeDocGenerateResult> results = new List<TradeDocGenerateResult>();
List<string> error = new List<string>();
List<string> file = new List<string>();
logger.Info("[GJGenerateConfirmBook] 生成确认书流程");
if (tradeIds == null || !tradeIds.Any())
{
logger.Info("[GJGenerateConfirmBook] tradeIds 为空,直接返回");
errors = new List<string>();
files = new List<string>();
return true;
}
var trades = DbContext.trade.Where(x => tradeIds.Contains(x.id)).AsNoTracking().ToList();
logger.Info($"[GJGenerateConfirmBook] 查询到交易记录数: {trades.Count}");
if (!trades.Any())
{
logger.Info("[GJGenerateConfirmBook] 未找到交易记录,直接返回");
errors = new List<string>();
files = new List<string>();
return true;
}
// 过滤掉待确认和审批中的交易,这些状态不允许生成确认书
var invalidStatusList = new List<string> { ConsTrade.新增待确认, ConsTrade.修改待确认, ConsTrade.审批中 };
var invalidTrades = trades.Where(t => invalidStatusList.Contains(t.TradeStatus)).ToList();
if (invalidTrades.Any())
{
error.AddRange(invalidTrades.Select(t => $"交易 {t.TradeNumber} 状态为【{t.TradeStatus}】,不能生成确认书"));
tradeIds = tradeIds.Where(id => !invalidTrades.Any(t => t.id == id)).ToList();
trades = trades.Where(t => !invalidTrades.Any(it => it.id == t.id)).ToList();
logger.Info($"[GJGenerateConfirmBook] 过滤掉 {invalidTrades.Count} 笔待确认/审批中交易");
}
if (!trades.Any())
{
logger.Info("[GJGenerateConfirmBook] 过滤后无有效交易可生成确认书");
errors = error;
files = new List<string>();
return false;
}
var clientIds = trades.Select(x => x.ClientId).Distinct().ToList();
logger.Info($"[GJGenerateConfirmBook] 客户ID数: {clientIds.Count}");
foreach (var item in trades)
{
groupGenerateHandle_Date(new List<int> { item.id }, docType, startDate, endDate, results, error, file);
}
errors = results.Where(n => !string.IsNullOrWhiteSpace(n.ErrorMessage)).Select(n => n.ErrorMessage).ToList();
files = results.Where(n => !string.IsNullOrWhiteSpace(n.OutputFilePath)).Select(n => n.OutputFilePath).ToList();
logger.Info($"[GJGenerateConfirmBook] 完成生成确认书 - 错误数: {errors.Count()}, 文件数: {files.Count()}");
return !errors.Any();
}
private void groupGenerateHandle_Date(List<int> ids, string docType, DateTime? startDate, DateTime? endDate, List<TradeDocGenerateResult> results, List<string> error, List<string> file)
{
var logger = LogFactory.GetLogger("生成确认书");
logger.Info($"[groupGenerateHandle_Date] 开始处理 - ids.Count: {ids?.Count ?? 0}");
if (ids == null || !ids.Any())
{
logger.Info("[groupGenerateHandle_Date] ids 为空,直接返回");
return;
}
var trades = DbContext.trade.Where(c => ids.Contains(c.id)).ToList();
logger.Info($"[groupGenerateHandle_Date] 查询到交易数: {trades.Count}");
if (!trades.Any())
{
logger.Info("[groupGenerateHandle_Date] 未找到交易记录,直接返回");
return;
}
var firstTrade = trades.FirstOrDefault();
if (firstTrade == null)
{
logger.Info("[groupGenerateHandle_Date] 第一条交易记录为 null,直接返回");
return;
}
var client = DataCacheProvider.GetClientDataSource().GetData(firstTrade.ClientId);
if (client == null)
{
logger.Info($"[groupGenerateHandle_Date] 未找到客户信息 - ClientId: {firstTrade.ClientId}");
return;
}
if (string.IsNullOrEmpty(client.Code))
{
throw new ServiceException($"对手方代码缩写缺失,请联系运营组同事维护: {firstTrade.ClientName}");
}
var supProtocolDate = client.SupProtocolDate;
logger.Info($"[groupGenerateHandle_Date] 客户补充协议日期: {supProtocolDate}");
var groupDateDouble = trades.Where(x => supProtocolDate == null || x.TradeDate < supProtocolDate).Select(x => x.id).ToList();
var groupDateSingle = trades.Where(x => supProtocolDate != null && x.TradeDate >= supProtocolDate).Select(x => x.id).ToList();
logger.Info($"[groupGenerateHandle_Date] 双章确认书交易数: {groupDateDouble.Count}, 单章确认书交易数: {groupDateSingle.Count}");
// 单章确认书和双章确认书同时生成要生成两个文件
if (groupDateDouble.Any() && groupDateSingle.Any())
{
logger.Info("[groupGenerateHandle_Date] 同时生成单章和双章确认书");
groupGenerateHandle(groupDateDouble, docType, startDate, supProtocolDate.Value.AddDays(-1), results, error, file);
groupGenerateHandle(groupDateSingle, docType, supProtocolDate, endDate, results, error, file);
}
else if (groupDateDouble.Any())
{
logger.Info("[groupGenerateHandle_Date] 仅生成双章确认书");
groupGenerateHandle(groupDateDouble, docType, startDate, endDate, results, error, file);
}
else if (groupDateSingle.Any())
{
logger.Info("[groupGenerateHandle_Date] 仅生成单章确认书");
groupGenerateHandle(groupDateSingle, docType, startDate, endDate, results, error, file);
}
else
{
logger.Info("[groupGenerateHandle_Date] 没有需要生成的确认书");
}
}
private void groupGenerateHandle(List<int> ids, string docType, DateTime? startDate, DateTime? endDate, List<TradeDocGenerateResult> results, List<string> error, List<string> file)
{
var logger = LogFactory.GetLogger("生成确认书");
logger.Info($"[groupGenerateHandle] 开始处理 - ids.Count: {ids?.Count ?? 0}, docType: {docType}");
if (ids == null || !ids.Any())
{
logger.Info("[groupGenerateHandle] ids 为空,直接返回");
return;
}
var trade_contract_r = DbContext.trade_contract_r.Where(c => ids.Contains(c.TradeId) && c.Type == "交易确认书" && c.IsValid).ToList();
logger.Info($"[groupGenerateHandle] 找到已存在的确认书记录数: {trade_contract_r.Count}");
//DbContext.trade_contract_r.RemoveRange(trade_contract_r);
trade_contract_r.ForEach(O => O.IsValid = false);
DbContext.SaveChanges();
logger.Info("[groupGenerateHandle] 调用 BatchConfirmationGenerateService.Generate");
var result = new BatchConfirmationGenerateService(this).Generate(ids, docType, startDate, endDate);
logger.Info($"[groupGenerateHandle] 生成结果 - 成功数: {result.Count(r => string.IsNullOrWhiteSpace(r.ErrorMessage))}, 失败数: {result.Count(r => !string.IsNullOrWhiteSpace(r.ErrorMessage))}");
results.AddRange(result);
error.AddRange(results.Where(n => !string.IsNullOrWhiteSpace(n.ErrorMessage)).Select(n => n.ErrorMessage).ToArray());
file.AddRange(results.Where(n => !string.IsNullOrWhiteSpace(n.OutputFilePath)).Select(n => n.OutputFilePath).ToList());
logger.Info($"[groupGenerateHandle] 完成处理 - 当前总错误数: {error.Count}, 当前总文件数: {file.Count}");
}
public bool GXJY_CorrespondingConfirmationTemplate(List<int> tradeIds, out string ErrMsg)
{
bool IsExist = true;
ErrMsg = "";
var listTrade = DbContext.trade.Where(l => tradeIds.Contains(l.id));
foreach (var t in listTrade)
{
bool IsExistChild = false;
var exerciseMode = t.ExerciseMode ?? "";
switch (t.TradeType)
{
case "亚式期权":
IsExistChild = true;
break;
case "结构化交易":
switch (t.StructureType)
{
case "普通亚式带保底":
case "增强亚式":
case "增强亚式价差":
case "增强亚式价差组合标的":
IsExistChild = true;
break;
}
break;
default:
IsExistChild = true;
break;
}
if (IsExistChild == false)
{
IsExist = false;
ErrMsg += t.TradeNumber.ToString() + ",";
}
}
if (!string.IsNullOrWhiteSpace(ErrMsg))
{
ErrMsg = ErrMsg.Substring(0, ErrMsg.Length - 1);
ErrMsg += "该交易没有相应确认书模板";
}
return IsExist;
}
/// <summary>
/// 生成提前中止确认书
/// </summary>
public bool GJGenerateUnwindReport(List<UnwindReportInputModel> trades, string docType,
out List<string> errors, out List<string> files)
{
var tdIds = trades.Select(t => t.TradeId).ToList();
if (PS.Config.Company == CompanyEnum.国信金阳)
{
var IsTradeContract = DbContext.trade_contract_r.Where(l => l.IsValid && tdIds.Contains(l.TradeId) && l.Type == "交易确认书").Select(l => l.TradeId).ToList();
var IsTradeIds = tdIds.Where(l => !IsTradeContract.Contains(l)).ToList();
if (IsTradeIds.Count > 0)
{
throw new ServiceException(String.Join(",", DbContext.trade.Where(l => IsTradeIds.Contains(l.id)).Select(l => l.TradeNumber).ToArray()) + "请生成该交易编号相应交易确认书");
}
if (!GXJY_CorrespondingConfirmationTemplate(tdIds, out string Msg))
{
throw new ServiceException(Msg);
}
}
files = new List<string>();
errors = new List<string>();
if (PS.Config.Company == CompanyEnum.兴证)
{
IEnumerable<TradeDocGenerateResult> results = null;
results = new BatchUnwindReportGenerateService(this).Generate(trades, docType, UserId, UserName);
errors = results.Where(n => !string.IsNullOrWhiteSpace(n.ErrorMessage)).Select(n => n.ErrorMessage).ToList();
files = results.Where(n => !string.IsNullOrWhiteSpace(n.OutputFilePath)).Select(n => n.OutputFilePath).ToList();
}
else if (PS.Config.Company == CompanyEnum.海通)
{
var tradeCashIds = trades.Select(O => O.TradeCashId);
var tradeCashStatus = new string[] { ClientCashInCashOut.系统操作_行权费, ClientCashInCashOut.系统操作_平仓费 };
var query = from t in DbContext.trade
join tc in DbContext.trade_cash
on t.id equals tc.TradeId
where
tradeCashIds.Contains(tc.id) &&
tc.ValidState != ConsGlobal.InValid && !tc.IsDeleted &&
tradeCashStatus.Contains(tc.Action) &&
tc.ExerciseWay == TradeCashExerciseWayEnum.提前终止行权
select new { t.id, tradeCashId = tc.id, t.ClientId };
var clientTradeDict = query.AsEnumerable().GroupBy(O => O.ClientId)
.ToDictionary(K => K.Key, V => V.Select(O => new UnwindReportInputModel() { TradeId = O.id, TradeCashId = O.tradeCashId }).ToList());
foreach (var ctrades in clientTradeDict)
{
var results = new BatchUnwindReportGenerateService(this).Generate(ctrades.Value, "PDF", UserId, UserName);
errors.AddRange(results.Where(n => !string.IsNullOrWhiteSpace(n.ErrorMessage)).Select(n => n.ErrorMessage).ToArray());
files.AddRange(results.Where(n => !string.IsNullOrWhiteSpace(n.OutputFilePath)).Select(n => n.OutputFilePath).ToList());
if (errors.Any()) break;
}
}
else if (PS.Config.Is方顿) //同一笔交易结构化交易在一个确认书里
{
List<TradeDocGenerateResult> results = new List<TradeDocGenerateResult>();
List<string> error = new List<string>();
List<string> file = new List<string>();
var tradeIds = trades.Select(O => O.TradeId).ToArray();
var query = DbContext.trade.Where(O => tradeIds.Contains(O.id)).Select(O => new { O.id, O.ParentTradeId }).ToList();
var group = query.GroupBy(O => O.ParentTradeId).ToDictionary(K => K.Key, V => V.Select(O => O.id).ToList());
foreach (var item in group)
{
if (item.Key == 0)
{
foreach (var item2 in item.Value)
{
var tradeCashIds = trades.Where(x => x.TradeId == item2).ToList();
var CashIds = trades.Where(x => x.TradeId == item2).Select(x => x.TradeId).ToList();
var trade_contract_r = DbContext.trade_contract_r.Where(c => CashIds.Contains(c.TradeCashId.Value) && c.IsValid).ToList();
trade_contract_r.ForEach(o => o.IsValid = false);
DbContext.SaveChanges();
var result = new BatchUnwindReportGenerateService(this).Generate(tradeCashIds, docType, UserId, UserName);
results.AddRange(result);
error.AddRange(results.Where(n => !string.IsNullOrWhiteSpace(n.ErrorMessage)).Select(n => n.ErrorMessage).ToArray());
file.AddRange(results.Where(n => !string.IsNullOrWhiteSpace(n.OutputFilePath)).Select(n => n.OutputFilePath).ToList());
if (error.Any()) break; ;
}
}
else
{
var tradeCashIds = (from t1 in item.Value join tc in trades on t1 equals tc.TradeId select tc).ToList();
var CashIds = (from t1 in item.Value join tc in trades on t1 equals tc.TradeId select tc.TradeId).ToList();
var trade_contract_r = DbContext.trade_contract_r.Where(c => CashIds.Contains(c.TradeCashId.Value) && c.IsValid).ToList();
trade_contract_r.ForEach(o => o.IsValid = false);
DbContext.SaveChanges();
var result = new BatchUnwindReportGenerateService(this).Generate(tradeCashIds, docType, UserId, UserName);
results.AddRange(result);
error.AddRange(results.Where(n => !string.IsNullOrWhiteSpace(n.ErrorMessage)).Select(n => n.ErrorMessage).ToArray());
file.AddRange(results.Where(n => !string.IsNullOrWhiteSpace(n.OutputFilePath)).Select(n => n.OutputFilePath).ToList());
if (error.Any()) break; ;
}
}
errors = results.Where(n => !string.IsNullOrWhiteSpace(n.ErrorMessage)).Select(n => n.ErrorMessage).ToList();
files = results.Where(n => !string.IsNullOrWhiteSpace(n.OutputFilePath)).Select(n => n.OutputFilePath).ToList();
}
else
{
List<TradeDocGenerateResult> results = new List<TradeDocGenerateResult>();
if (PS.Config.Is国泰君安)
{
List<string> error = new List<string>();
List<string> file = new List<string>();
var tradeIds = trades.Select(O => O.TradeId);
var tradecashId = trades.Select(o => o.TradeCashId).ToList();
Func<int, string> getUnderlyingInstrumentType = new Func<int, string>((underlyingId) =>
{
return DataCacheProvider.GetUnderlyingDataSource().GetData(underlyingId).UnderlyingInstrumentType;
});
List<string> instrumentTypeArr = new List<string>() { ConsGlobal.InstrumentType.Stock, ConsGlobal.InstrumentType.StockIF };
var query = DbContext.trade.Where(O => tradeIds.Contains(O.id)).Select(O => new { O.id, O.UnderlyingId, O.ClientId, O.TradeType }).ToList();
if (query.Any(O => instrumentTypeArr.Contains(getUnderlyingInstrumentType(O.UnderlyingId)) || O.TradeType == "雪球期权"))
{
//暂时将所有子交易都作为判断依据,等拿到模板后再根据模板做调整更改;
//目前是否为权益类的判断条件只是是否是股票,没有考虑IC IF等品种;
int count = query.GroupBy(O => new { UnderlyingInstrumentType = (instrumentTypeArr.Contains(getUnderlyingInstrumentType(O.UnderlyingId)) || O.TradeType == "雪球期权") ? 1 : 0 }).Count();
if (count > 1)
{
throw new ServiceException("不应勾选多个非股票(含股指期货)标的的交易");
}
var group = query.GroupBy(O => new { O.ClientId }).ToDictionary(K => K.Key, V => V.Select(O => O.id).ToList());
foreach (var item in group)
{
var tradeCashIds = (from t1 in item.Value join tc in trades on t1 equals tc.TradeId select tc).ToList();
var CashIds = (from t1 in item.Value join tc in trades on t1 equals tc.TradeId select tc.TradeId).ToList();
var trade_contract_r = DbContext.trade_contract_r.Where(c => CashIds.Contains(c.TradeCashId.Value) && c.IsValid).ToList();
//DbContext.trade_contract_r.RemoveRange(trade_contract_r);
trade_contract_r.ForEach(o => o.IsValid = false);
DbContext.SaveChanges();
var result = new BatchUnwindReportGenerateService(this).Generate(tradeCashIds, docType, UserId, UserName);
results.AddRange(result);
error.AddRange(results.Where(n => !string.IsNullOrWhiteSpace(n.ErrorMessage)).Select(n => n.ErrorMessage).ToArray());
file.AddRange(results.Where(n => !string.IsNullOrWhiteSpace(n.OutputFilePath)).Select(n => n.OutputFilePath).ToList());
if (error.Any()) break; ;
}
}
}
if (results.Count == 0)
{
results = (List<TradeDocGenerateResult>)new UnwindReportGenerateService(this).Generate(trades, docType);
}
errors = results.Where(n => !string.IsNullOrWhiteSpace(n.ErrorMessage)).Select(n => n.ErrorMessage).ToList();
files = results.Where(n => !string.IsNullOrWhiteSpace(n.OutputFilePath)).Select(n => n.OutputFilePath).ToList();
}
return !errors.Any();
}
/// <summary>
/// 生成结算确认书
/// </summary>
public bool GJGenerateSettleBill(List<int> tradeIds, string docType,
out IEnumerable<string> errors, out IEnumerable<string> files)
{
IEnumerable<TradeDocGenerateResult> results;
var settleSv = new SettlementBillGenerateService(this);
results = settleSv.Generate(null, tradeIds, docType, UserId, UserName);
errors = results.Where(n => !string.IsNullOrWhiteSpace(n.ErrorMessage)).Select(n => n.ErrorMessage).ToArray();
files = results.Where(n => !string.IsNullOrWhiteSpace(n.OutputFilePath)).Select(n => n.OutputFilePath).ToArray();
return !errors.Any();
}
/// <summary>
/// 根据传进来的合约代码过滤出已存在的合约代码
/// </summary>
public IEnumerable<string> GetExistsContractCode(IEnumerable<string> contractCodes)
{
if (contractCodes == null)
{
throw new ArgumentNullException(nameof(contractCodes));
}
if (!contractCodes.Any())
{
return Enumerable.Empty<string>();
}
var query = (from a in DbContext.trade_contract_r.AsNoTracking()
join b in DbContext.trade.AsNoTracking() on a.TradeId equals b.id
where contractCodes.Contains(a.ContractCode) && b.ValidState != "InValid" && a.IsValid
select a.ContractCode).Union
(from tm in DbContext.TradeMeta.AsNoTracking()
join t in DbContext.trade.AsNoTracking() on tm.TradeId equals t.id
where (tm.MetaKey == ConsTradeMetaKey.ContractCode || tm.MetaKey.Contains("确认书")) && //伴星确认书编号的Key是合约编号,长江确认书编号的Key是日期+(交易确认书、结算确认书和提前终止确认书)+序号
t.ValidState != "InValid"
&& contractCodes.Contains(tm.MetaValue)
select tm.MetaValue);
//.Union
//(from t in DbContext.trade.AsNoTracking()
// where t.ValidState != "InValid" && contractCodes.Contains(t.TradeNumber)
// select t.TradeNumber);
return query.ToArray();
}
public SearchListResult<clientContractR> GetConfirmBookListByClient(ClientConfirmBookListReq req)
{
var result = new SearchListResult<clientContractR>();
var contractList = new List<clientContractR>();
var query = from t in DbContext.trade.AsNoTracking().Where(x => x.TradeType == "收益互换" && x.ValidState != "InValid")
join tcrs in DbContext.trade_contract_r
on t.id equals tcrs.TradeId into tcrsGroup
from tcr in tcrsGroup.Where(r => r.IsValid && r.Type == ContractTypeEnum.Trade).DefaultIfEmpty()
join tcds in DbContext.trade_contract_document
on tcr.ContractCode equals tcds.Code into tcdsGroup
from tcd in tcdsGroup.DefaultIfEmpty()
join sp in DbContext.swap_position.AsNoTracking().Where(s => s.IsInitial && s.PositionType > 0 && !s.Invalid)
on t.id equals sp.SwapTradeId
join oa in DbContext.tradeContractOaResult on t.id equals oa.trade_id into oaTemp
from oa in oaTemp.DefaultIfEmpty()
where oa == null || oa.is_valid == true
select new
{
t.id,
t.TradeDate,
t.StartDate,
tcr.ContractCode,
t.ClientId,
t.ClientNumber,
t.ClientName,
tcr.send_email_result,
tcd.Status,
tcd.RelativePath,
tcd.SealResult,
ContractId = tcr != null ? tcr.id : 0,
sp.PositionType,
t.SentMailCount,
tcd.StampDocumentFileName,
tcr.OptDate,
tcr.OptName,
ContractDocId = tcd != null ? tcd.id : 0,
OAStatus = oa != null ? oa.status : "",
OAURL = oa != null ? oa.oa_url : "",
OAMessage = oa != null ? oa.oa_msg : ""
};
if (req.StartDate != null && req.StartDate != DateTime.MinValue)
{
query = query.Where(o => o.TradeDate >= req.StartDate);
}
if (req.EndDate != null && req.EndDate != DateTime.MaxValue)
{
query = query.Where(o => o.TradeDate <= req.EndDate);
}
if (req.ClientIds != null && req.ClientIds.Count > 0)
{
query = query.Where(o => req.ClientIds.Contains(o.ClientId));
}
if (!string.IsNullOrEmpty(req.ContractCode))
{
query = query.Where(o => o.ContractCode.Contains(req.ContractCode));
}
if (req.PositionTypes != null && req.PositionTypes.Count() > 0)
{
query = query.Where(o => req.PositionTypes.Contains(o.PositionType));
}
//客户希望用StartDate分组, 默认业务中StartDate会是TradeDate+1个交易日
var contractGroups = query.AsEnumerable()
.GroupBy(x => new { x.StartDate, x.ClientId, x.PositionType })
.Select(group => group.ToList())
.ToList();
// 构建返回结果
foreach (var group in contractGroups)
{
var sealResult = group.FirstOrDefault().SealResult;
contractList.Add(new clientContractR
{
id = group.FirstOrDefault().id,
ContractCode = group.FirstOrDefault().ContractCode,
TradeDate = group.FirstOrDefault().TradeDate.Value,
ClientNumber = group.FirstOrDefault().ClientNumber,
ClientName = group.FirstOrDefault().ClientName,
StampStatus = group.FirstOrDefault().Status,
EmailResult = group.FirstOrDefault().send_email_result,
ContractDocUrl = group.FirstOrDefault().RelativePath,
tradeIds = group.Select(x => x.id).Distinct().ToList(),
SealResult = sealResult != null ? Enum.GetName(typeof(SealResultEnum), sealResult) : "",
HasGeneratedConfirmBook = group.FirstOrDefault().ContractId != 0,
ContractId = group.FirstOrDefault().ContractId,
tradeCount = group.Select(x => x.id).Distinct().Count(),
PositionType = group.FirstOrDefault().PositionType,
SentMailCount = group.FirstOrDefault().SentMailCount ?? 0,
StampDocumentFileName = group.FirstOrDefault().StampDocumentFileName,
OptDate = group.FirstOrDefault().OptDate,
OptName = group.FirstOrDefault().OptName,
ContractDocId = group.FirstOrDefault().ContractDocId,
OAStatus = group.FirstOrDefault().OAStatus,
OAURL = group.FirstOrDefault().OAURL,
OAMessage = group.FirstOrDefault().OAMessage
});
}
result = contractList.OrderByDescending(r => r.TradeDate).AsQueryable().ToSearchList(req);
return result;
}
}
/// <summary>
/// 交易确认书生成结果
/// </summary>
public class TradeContractGenerateResultModel
{
public bool Success;
public string Message;
public string ContractType;
public Exception Exception;
}
public class ClientConfirmBookListReq : BaseSearchReq
{
//合约编号
public string ContractCode { get; set; }
//开仓起始时间
public DateTime? StartDate { get; set; }
//开仓结束时间
public DateTime? EndDate { get; set; }
//客户
public List<int>? ClientIds { get; set; }
public List<int>? PositionTypes { get; set; }
}
public class clientContractR
{
public int id { get; set; }
public string ContractCode { get; set; }
public DateTime TradeDate { get; set; }
public string ClientNumber { get; set; }
public string ClientName { get; set; }
public string StampStatus { get; set; }
public string EmailResult { get; set; }
public List<int> tradeIds { get; set; }
public string ContractDocUrl { get; set; }
public string SealResult { get; set; }
public string ContractEncryptId { get; set; }
public bool HasGeneratedConfirmBook { get; set; }
public int ContractId { get; set; }
public int PositionType { get; set; }
public int tradeCount { get; set; }
public int SentMailCount { get; set; }
public string StampDocumentFileName { get; set; }
public DateTime? OptDate { get; set; }
public string OptName { get; set; }
public int ContractDocId { get; set; }
public string OAStatus { get; set; }
public string OAURL { get; set; }
public string OAMessage { get; set; }
}
}