Files
zszq-trs/YLErpDAL/Modules/TradeModule/DealModule/TradeContractGenerateService.cs
T
2024-05-09 14:06:26 +08:00

700 lines
37 KiB
C#

using BaseOUDAL;
using System.Collections.Concurrent;
using YLErp.Configuration;
using YLErp.DBModels.Consts;
using YLErp.Model;
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)
{
if (PS.Config.Company == CompanyEnum.国信金阳)
{
if (!GXJY_CorrespondingConfirmationTemplate(tradeIds, out string Msg))
{
throw new ServiceException(Msg);
}
}
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>();
if (PS.Config.Is国泰君安 || PS.Config.Is厦门象屿)
{
var Tradelist = new TradeDalService(this).GetTradeOrEodTradeOfTidAPid(tradeIds, SystemValueDate, false, false);
using (var basedb = new ErpBaseContext())
{
if (Tradelist.Any(O => O.IsGroup > 0))
{
int count = Tradelist.Where(O => O.IsGroup != 2).GroupBy(O => O.IsGroup).Count();
if (count > 1)
{
throw new ServiceException("不应勾选多个非黑盒标的的交易");
}
var list = Tradelist.Where(x => x.TradeType == "结构化交易");
var group = list.GroupBy(O => new { O.ClientId, O.StructureType }).ToDictionary(K => K.Key, V => V.Select(O => O.id).ToList());
foreach (var item in group)
{
if (item.Key.StructureType == "折价")
{
var list2 = list.Where(x => item.Value.Contains(x.id) && x.TradeType == "结构化交易").ToList();
list2.ForEach(x =>
{
var options = x.Propertys?.Where(o => o.name == "看涨看跌").ToList();
if (options != null && options.Any())
{
x.ExtendOptionTypeInfo = JsonHelper.Serialize(options);
}
else
{
throw new ServiceException("看涨看跌不能为空:" + x.TradeNumber);
}
});
var group2 = list2.GroupBy(O => O.ExtendOptionTypeInfo).ToDictionary(K => K.Key, V => V.Select(O => O.id).ToList());
foreach (var item2 in group2)
{
groupGenerateHandle_Date(item2.Value, docType, startDate, endDate, results, error, file);
if (error.Any()) break;
}
}
else
{
groupGenerateHandle_Date(item.Value, docType, startDate, endDate, results, error, file);
if (error.Any()) break;
}
}
var swapList = Tradelist.Where(x => x.TradeType == "收益互换" && x.ParentTradeId == 0);
foreach (var item in swapList)
{
groupGenerateHandle_Date(new List<int> { item.id }, docType, startDate, endDate, results, error, file);
}
}
}
if (results.Count == 0)
{
var structTradeQuery = new TradeDalService(this).GetTradeOrEodTradeOfTidASid(tradeIds, SystemValueDate).Where(c => c.TradeType != "结构化交易");
List<string> instrumentTypeArr = new List<string>() { ConsGlobal.InstrumentType.Stock, ConsGlobal.InstrumentType.StockIndex, ConsGlobal.InstrumentType.StockIF };
DataCacheProvider.GetUnderlyingDataSource().AsQueryable();
if (structTradeQuery.Any(O => instrumentTypeArr.Contains(getUnderlyingInstrumentType(O.UnderlyingId)) || O.TradeType == "雪球期权"))
{
//暂时将所有子交易都作为判断依据,等拿到模板后再根据模板做调整更改;
//目前是否为权益类的判断条件只是是否是股票,没有考虑IC IF等品种;
int count = structTradeQuery.GroupBy(O => new { UnderlyingInstrumentType = (instrumentTypeArr.Contains(getUnderlyingInstrumentType(O.UnderlyingId)) || O.TradeType == "雪球期权") ? 1 : 0 }).Count();
if (count > 1)
{
throw new ServiceException("不应勾选多个非股票(含股指期货)标的的交易");
}
var group = structTradeQuery.GroupBy(O => new { O.ClientId, O.TradeType }).ToDictionary(K => K.Key, V => V.Select(O => O.id).ToList());
foreach (var item in group)
{
if (item.Key.TradeType == "雪球期权")
{
if (structTradeQuery.Any(O => !instrumentTypeArr.Contains(getUnderlyingInstrumentType(O.UnderlyingId))))
{
var group2 = DbContext.trade.Where(c => item.Value.Contains(c.id)).AsEnumerable().GroupBy(m => m.OptionType).ToDictionary(K => K.Key, V => V.Select(O => O.id).ToList());
foreach (var item2 in group2)
{
groupGenerateHandle_Date(item2.Value, docType, startDate, endDate, results, error, file);
if (error.Any()) break;
}
}
else
{
var group2 = DbContext.trade_snowball.Where(c => item.Value.Contains(c.TradeId)).AsEnumerable().GroupBy(m => m.IsFixedCoupon).ToDictionary(K => K.Key, V => V.Select(O => O.TradeId).ToList());
foreach (var item2 in group2)
{
if (item2.Key)
{
groupGenerateHandle_Date(item2.Value, docType, startDate, endDate, results, error, file);
if (error.Any()) break;
}
else
{
var group3 = DbContext.trade.Where(c => item2.Value.Contains(c.id)).AsEnumerable().GroupBy(m => m.OptionType).ToDictionary(K => K.Key, V => V.Select(O => O.id).ToList());
foreach (var item3 in group3)
{
groupGenerateHandle_Date(item3.Value, docType, startDate, endDate, results, error, file);
if (error.Any()) break;
}
}
}
}
}
else
{
groupGenerateHandle_Date(item.Value, docType, startDate, endDate, results, error, file);
if (error.Any()) break;
}
}
}
}
}
else if (PS.Config.Is润和)
{
var TradeQuery = new TradeDalService(this).GetTradeOrEodTradeOfTidASid(tradeIds, SystemValueDate).Where(c => (c.TradeType != "结构化交易" || c.IsGroup == 1) && tradeIds.Contains(c.id));
if (TradeQuery.Any())
{
var group = TradeQuery.GroupBy(O => new { O.ClientId, O.TradeDate }).ToDictionary(K => K.Key, V => V.Select(O => O.id).ToList());
foreach (var item in group)
{
var group2 = DbContext.trade.Where(c => item.Value.Contains(c.id) && c.TradeType == "远期").Select(O => O.id).ToList();
if (group2.Any())
{
groupGenerateHandle(group2, docType, startDate, endDate, results, error, file);
if (error.Any()) break;
}
var group4 = DbContext.trade.Where(c => item.Value.Contains(c.id) && c.TradeType == "亚式期权").Select(O => O.id).ToList();
if (group4.Any())
{
groupGenerateHandle(group4, docType, startDate, endDate, results, error, file);
if (error.Any()) break;
}
var group3 = DbContext.trade.Where(c => item.Value.Contains(c.id) && c.TradeType != "远期" && c.TradeType != "亚式期权").Select(O => O.id).ToList();
if (group3.Any())
{
groupGenerateHandle(group3, docType, startDate, endDate, results, error, file);
if (error.Any()) break;
}
}
}
}
else if (PS.Config.Is东吴)
{
var TradeQuery = new TradeDalService(this).GetTradeOrEodTradeOfTidASid(tradeIds, SystemValueDate).Where(c => (c.TradeType != "结构化交易" || c.IsGroup == 1) && tradeIds.Contains(c.id));
if (TradeQuery.Any())
{
var group = TradeQuery.GroupBy(O => new { O.ClientId, O.TradeDate }).ToDictionary(K => K.Key, V => V.Select(O => O.id).ToList());
foreach (var item in group)
{
var query = from t in DbContext.trade
join tc in DbContext.trade_cash on t.id equals tc.TradeId
where t.ClientId == item.Key.ClientId &&
tc.ValueDate == item.Key.TradeDate && !tc.IsDeleted && tc.Action == ClientCashInCashOut.系统操作_期权费
select new { t.id };
if (query.Any())
{
groupGenerateHandle(query.Select(l => l.id).ToList(), docType, startDate, endDate, results, error, file);
}
}
}
}
else if(PS.Config.Is物产中大)
{
var TradeQuery = new TradeDalService(this).GetTradeOrEodTradeOfTidASid(tradeIds, SystemValueDate).Where(c => (c.TradeType != "结构化交易" || c.IsGroup == 1) && tradeIds.Contains(c.id));
if (TradeQuery.Any())
{
var group = TradeQuery.GroupBy(O => new { O.ClientId, O.TradeDate,O.TradeType }).ToDictionary(K => K.Key, V => V.Select(O => O.id).ToList());
foreach (var item in group)
{
if (item.Value.Count > 10)
{
throw new ServiceException("同客户同日期同类型交易生成超过限制!");
}
var query = from t in DbContext.trade
join tc in DbContext.trade_cash on t.id equals tc.TradeId
where item.Value.Contains(tc.TradeId) && !tc.IsDeleted
select new { t.id };
if (query.Any())
{
groupGenerateHandle(query.Select(l => l.id).ToList(), docType, startDate, endDate, results, error, file);
}
}
}
}
if (results.Count == 0)
{
results = new ConfirmationGenerateService(this).Generate(tradeIds, 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();
}
private void groupGenerateHandle_Date(List<int> ids, string docType, DateTime? startDate, DateTime? endDate, List<TradeDocGenerateResult> results, List<string> error, List<string> file)
{
var trades = DbContext.trade.Where(c => ids.Contains(c.id)).ToList();
var supProtocolDate = DataCacheProvider.GetClientDataSource().GetData(trades.FirstOrDefault().ClientId).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();
// 单章确认书和双章确认书同时生成要生成两个文件
if (groupDateDouble.Any() && groupDateSingle.Any())
{
groupGenerateHandle(groupDateDouble, docType, startDate, supProtocolDate.Value.AddDays(-1), results, error, file);
groupGenerateHandle(groupDateSingle, docType, supProtocolDate, endDate, results, error, file);
}
else if (groupDateDouble.Any())
{
groupGenerateHandle(groupDateDouble, docType, startDate, endDate, results, error, file);
}
else if (groupDateSingle.Any())
{
groupGenerateHandle(groupDateSingle, docType, startDate, endDate, results, error, file);
}
}
private void groupGenerateHandle(List<int> ids, string docType, DateTime? startDate, DateTime? endDate, List<TradeDocGenerateResult> results, List<string> error, List<string> file)
{
var trade_contract_r = DbContext.trade_contract_r.Where(c => ids.Contains(c.TradeId) && c.Type == "交易确认书" && c.IsValid).ToList();
//DbContext.trade_contract_r.RemoveRange(trade_contract_r);
trade_contract_r.ForEach(O => O.IsValid = false);
DbContext.SaveChanges();
var result = new BatchConfirmationGenerateService(this).Generate(ids, docType, startDate, endDate);
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());
}
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();
}
}
/// <summary>
/// 交易确认书生成结果
/// </summary>
public class TradeContractGenerateResultModel
{
public bool Success;
public string Message;
public string ContractType;
public Exception Exception;
}
}