TRS-ZS-183 一个客户一天所有开仓的多头交易都放到一个交易确认书里

This commit is contained in:
锦麟 王
2025-04-22 09:45:21 +08:00
parent 4b9bcfb2dc
commit 5ba29de3ed
21 changed files with 1176 additions and 393 deletions
@@ -1,8 +1,10 @@
using BaseOUDAL;
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;
@@ -207,187 +209,34 @@ namespace YLErp.Modules.TradeModule.DealModule
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润和)
if (PS.Config.Company == CompanyEnum.)
{
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 Ids = TradeQuery.Select(o => o.id).Distinct().ToArray();
var swapPositions = DbContext.swap_position.Where(s => Ids.Contains(s.SwapTradeId) && s.IsInitial && s.PositionType > 0 && !s.Invalid)
.Distinct().ToList();
foreach (var item in TradeQuery)
{
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;
}
item.swap_positions.Add(swapPositions.FirstOrDefault(o => o.SwapTradeId == item.id));
}
}
}
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());
// 按照客户ID、交易日期、多空头进行分组
var group = TradeQuery.GroupBy(O => new { O.ClientId, O.TradeDate, O.swap_positions.FirstOrDefault().PositionType})
.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);
// 使用现有的 groupGenerateHandle 方法来处理每组交易
groupGenerateHandle(query.Select(l => l.id).Distinct().ToList(), docType, startDate, endDate, results, error, file);
}
}
}
@@ -681,6 +530,97 @@ namespace YLErp.Modules.TradeModule.DealModule
return query.ToArray();
}
public SearchListResult<clientContractR> GetConfirmBookListByClient(ClientConfirmBookListReq req)
{
var result = new SearchListResult<clientContractR>();
var contractList = new List<clientContractR>();
// Fix for the issue: CS1525, CS0746, CS1003
// The problem lies in the incorrect syntax for defining an anonymous type.
// Anonymous type members must be declared using member assignment or simple names.
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
select new
{
t.id,
t.TradeDate,
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
};
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));
}
var contractGroups = query.AsEnumerable()
.GroupBy(x => new { x.TradeDate, 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,
});
}
result = contractList.AsQueryable().ToSearchList(req);
return result;
}
}
/// <summary>
@@ -696,4 +636,58 @@ namespace YLErp.Modules.TradeModule.DealModule
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; }
}
}