using System.Data; using System.Linq.Expressions; namespace YLErp.Modules.TradeModule.ApiModule { /// /// api/v2/tradeDetailList /// public class TradeDetailQueryApiV2Service : YLBaseService { public TradeDetailQueryApiV2Service(OptUserInfo userInfo) : base(userInfo) { } public TradeDetailQueryApiV2Service(YLBaseService baseService) : base(baseService) { } /// /// /// public IEnumerable GetList(TradeDetailQueryApiV2Request queryModel) { if (queryModel.OptDate == DateTime.MinValue) { throw new ServiceException("操作时间 必须填写"); } var noneCashStatus = new[] { "新增待确认, 修改待确认, 审批中, 已拒绝, 平仓待复核, 行权待复核, 互换待复核, 提前终止拒绝" }; CreateTradePredicate(queryModel, out var noneCashPredicate, out var hasCashPredicate); List tempList = new List(); DbContext.SetDebugLog(); if (noneCashPredicate != null) { var list = DbContext.trade.Where(noneCashPredicate) .OrderBy(n => n.OptDate) .Select(n => new InnerDto { td = n, OptDate = n.OptDate }).ToPagedList(new PagedQueryModel { GetTotal = false, PageSize = 10000 }); tempList.AddRange(list.Items); } if (hasCashPredicate != null) { var query = from tc in DbContext.trade_cash join t in DbContext.trade.Where(hasCashPredicate) on tc.TradeId equals t.id where tc.OptDate.Value > queryModel.OptDate && !tc.IsDeleted && tc.ValidState != ConsGlobal.InValid orderby tc.OptDate.Value select new InnerDto { td = t, tc = tc.Action == "系统操作-期权费" ? null : new TradeCloseInfo { TcAction = tc.Action, TcAmount = tc.Amount, TcFinalPrice = tc.FinalPrice, TcNotional = tc.Notional, TcTradeAmount = tc.TradeAmount, TcUnwindNotional = tc.UnwindNotional, TcUnwindPercent = tc.UnwindPercentRate, TcUnwindPrice = tc.UnwindPrice, TcUnwindPricePercent = tc.UnwindPricePercentRate, TcUnwindTradeAmount = tc.UnwindTradeAmount, TcValueDate = tc.ValueDate, TradeNumber = null, TcTradePrice = 0, WinLoss = 0 }, OptDate = tc.OptDate }; var list = query.ToPagedList(new PagedQueryModel { GetTotal = false, PageSize = 10000 }); tempList.AddRange(list.Items); } var resultList = tempList.Select(n => { var otcTrade = new TradeDetailQueryApiV2Result(); YLAutoMapper.Map(n.td, otcTrade); otcTrade.Notional = otcTrade.OriginalNotional ?? 0; otcTrade.StockEqvNotional = otcTrade.OriginalStockEqvNotional ?? 0; otcTrade.ClientNumber = ClientModule.ClientDataQueryService.GetClient(otcTrade.ClientId)?.Number; if (n.tc != null) { var closeInfo = n.tc; closeInfo.TradeNumber = n.td.TradeNumber; closeInfo.TcTradePrice = (otcTrade.TradePrice ?? 0) * (closeInfo.TcUnwindPercent ?? 0) * ((otcTrade.BuySell == "卖出" || otcTrade.TradeType == "远期") ? 1 : -1); closeInfo.WinLoss = (closeInfo.TcAmount ?? 0) + closeInfo.TcTradePrice; otcTrade.CloseInfo = closeInfo; } otcTrade.OptDate = n.OptDate; return otcTrade; }).ToArray(); new TradeExtendService(this).SetTradeExtend(resultList, true); return resultList; } /// /// 根据查询参数拼接查询条件 /// protected void CreateTradePredicate(TradeDetailQueryApiV2Request queryModel , out Expression> noneCashPredicate , out Expression> hasCashPredicate) { noneCashPredicate = hasCashPredicate = null; var predicate = PredicateBuilder.Create(t => t.ValidState != ConsGlobal.InValid); if (queryModel.IncludeGroupMain) { predicate = predicate.And(n => n.TradeType != "结构化交易" || n.IsGroup == 1); } else { predicate = predicate.And(n => n.TradeType != "结构化交易"); } // 结构类型 if (queryModel.StructureTypes.HasNonEmptyItem()) { predicate = predicate.And(d => queryModel.StructureTypes.Contains(d.TradeType) || queryModel.StructureTypes.Contains(d.StructureType)); } //客户 优先使用客户编号 var clientIds = GetClientIdsByNumber(queryModel.ClientNumbers) ?? GetClientIdsByName(queryModel.ClientNames); if (clientIds != null) { predicate = predicate.And(d => clientIds.Contains(d.ClientId)); } var noneCashStatus = new[] { "新增待确认", "修改待确认", "审批中", "已拒绝", "平仓待复核", "行权待复核", "互换待复核", "提前终止拒绝" }; //交易状态:确认成交、新增待确认、已平仓、已到期。。。等等 if (queryModel.TradeStatus != null && queryModel.TradeStatus.Any()) { noneCashStatus = noneCashStatus.Intersect(queryModel.TradeStatus).ToArray(); if (noneCashStatus.Any()) { noneCashPredicate = predicate.And(d => noneCashStatus.Contains(d.TradeStatus)); } var hasCashStatus = queryModel.TradeStatus.Except(noneCashStatus).ToArray(); if (hasCashStatus.Any()) { hasCashPredicate = predicate.And(d => hasCashStatus.Contains(d.TradeStatus)); } } else { hasCashPredicate = predicate; noneCashPredicate = predicate.And(d => noneCashStatus.Contains(d.TradeStatus)); } if (noneCashPredicate != null) { noneCashPredicate = noneCashPredicate.And(n => n.OptDate.Value > queryModel.OptDate); } } #region 先转换成id再构建查询条件 /// /// 根据交易对手方编号返回交易对手方ID /// /// 交易对手方编号 private List GetClientIdsByNumber(IEnumerable clientNumbers) { if (!clientNumbers.HasNonEmptyItem()) { return null; } using (var clientDbContext = DbContextFactory.GetClientDbContext(OptUser)) { return clientDbContext.client.Where(x => clientNumbers.Contains(x.Number)).Select(x => x.id).ToList(); } } /// /// 根据客户名称返回客户ID /// private List GetClientIdsByName(IEnumerable clientNames) { if (!clientNames.HasNonEmptyItem()) { return null; } using (var clientDbContext = DbContextFactory.GetClientDbContext(OptUser)) { return clientDbContext.client.Where(x => clientNames.Contains(x.Name)).Select(x => x.id).ToList(); } } #endregion class InnerDto { public trade td { get; set; } public TradeCloseInfo tc { get; set; } public DateTime? OptDate { get; set; } } } /// /// api/v2/tradeDetailList /// public class TradeDetailQueryApiV2Result : OtcOptionTradeFull { public TradeCloseInfo CloseInfo { get; set; } } }