using System.Text; using YLErp.BLL; using YLErp.BLL.Eod; using YLErp.Commons; using YLErp.DBModels.Consts; using YLErp.DBModels.Enums; using YLErp.DBModels.Helpers; using YLErp.Helpers; using YLErp.Model; using YLErp.Modules.CalculationModule; using YLErp.Modules.ClientModule; using YLErp.Modules.MarginModule; using YLErp.Modules.TradeModule.DealModule; namespace YLErp.Modules.TradeModule { /// /// 交易资金保存服务 /// 交易状态发生变化时调用检查对应资金对资金进行修改 /// public class ClientCashInCashOutService : TradeServiceBase { public ClientCashInCashOutService(YLBaseService baseService) : base(baseService) { } public ClientCashInCashOutService(OptUserInfo userInfo) : base(userInfo) { } /// /// 交易状态发生变化时调用检查对应资金对资金进行修改 /// public void SaveClientCashInCashOut(trade newtrade) { if (newtrade is null) { throw new ArgumentNullException(nameof(newtrade)); } if (ConsTrade.TradeTypesForHedge.Contains(newtrade.TradeType)) return; var valueDate = valuedateBLL.ValueDate; if (ConsTrade.TradeStatusBeforConfirmed.Contains(newtrade.TradeOldStatus) && newtrade.TradeStatus == ConsTrade.确认成交 && newtrade.TradeType != "收益互换") { if (newtrade.IsGroup == 1) { new TradeCashService(this).SaveGroupOpenTradeCash(newtrade); } else if (newtrade.TradeType == "结构化交易") { //当主交易确认时,待确认的子交易才有资金处理,已确认的子交易不该再处理,否则会产生多比有效的期权费数据 var childTrades = DbContext.trade.Where(x => x.ParentTradeId == newtrade.id && (x.TradeStatus == ConsTrade.修改待确认 || x.TradeStatus == ConsTrade.新增待确认 || x.TradeStatus == ConsTrade.审批中)).ToList(); foreach (var child in childTrades) { SaveTradeAndClientCash(child, valueDate); } } else { SaveTradeAndClientCash(newtrade, valueDate); } } } //保存clientcash和tradecash public void SaveTradeAndClientCash(trade newtrade, DateTime valueDate) { //增加现金交割交易记录 var tc = DbContext.trade_cash.FirstOrDefault(t => t.TradeId == newtrade.id && ClientCashInCashOut.系统操作_期权费.Equals(t.Action) && t.ValidState != ConsGlobal.InValid); if (tc == null) { tc = new trade_cash { ValidState = "Valid" }; DbContext.trade_cash.Add(tc); } tc.OptId = UserId; tc.OptName = UserName; tc.OptDate = DateTime.Now; tc.Action = ClientCashInCashOut.系统操作_期权费; tc.ExceciseType = "现金"; tc.TradeId = newtrade.id; tc.ValueDate = newtrade.TradeDate.Value; tc.Strike = newtrade.Strike; tc.Notional = newtrade.Notional; var metaPremium = DbContext.TradeMeta.Where(o => o.TradeId == newtrade.id && o.MetaKey == "交易溢价").FirstOrDefault(); if (metaPremium != null) { double.TryParse(metaPremium.MetaValue, out var premium); tc.TradePremium = premium; } if (newtrade.TradeType == "现金流交易") { tc.TradeAmount = 0; } else { var CountRatio = DataCacheProvider.GetUnderlyingDataSource().GetCountRatio(newtrade.UnderlyingCode); tc.TradeAmount = tc.Notional / CountRatio; } tc.Status = TradeCashStatusEnum.冻结; //trade_cash中方向为渠道方 所以如果为买入的话则为支出,卖出则为收入 if (newtrade.TradeType == "远期") { //对于远期,期权费就是开仓总手续费 //远期交易目前tradePrice是带方向的,所以这里不用加方向 tc.Amount = newtrade.TradePrice ?? 0; } else if (newtrade.TradeType == "现金流交易") { tc.Amount = (newtrade.BuySell == "买入" ? -1 : 1) * (newtrade.TradePrice ?? 0); } else { tc.Amount = (newtrade.BuySell == "买入" ? -1 : 1) * (newtrade.TradePrice ?? 0); tc.ExtraAmount = (newtrade.BuySell == "买入" ? -1 : 1) * newtrade.PrincipalSum(); } //交易方向 tc.TradeType = newtrade.BuySell; DbContext.SaveChanges(); //如果交易日期与权力金应付日期相同则增加出入金记录以及trade_cash信息(状态为已执行) if (null == newtrade.PremiumPayDate || newtrade.TradeDate == newtrade.PremiumPayDate) { var client = DataCacheProvider.GetClientDataSource().GetData(newtrade.ClientId); var cic = DbContext.ClientCashInCashOut.FirstOrDefault(t => t.TradeId == newtrade.id && t.ValidState != ConsGlobal.InValid && t.Action == ClientCashInCashOut.系统操作_期权费 && t.State != ClientCashInCashOut.已结算); bool addClientCash = false; if (cic == null) { addClientCash = true; cic = new ClientCashInCashOut() { CreateDate = DateTime.Now, CreatorId = UserId, CreatorName = UserName, HappenDate = (newtrade.PremiumPayDate ?? newtrade.TradeDate) == DateTime.Now.Date ? DateTime.Now : (newtrade.PremiumPayDate ?? newtrade.TradeDate) }; } cic.ClientId = newtrade.ClientId; cic.ClientName = newtrade.ClientName; cic.ClientNumber = client.Number; cic.TradeId = newtrade.id; cic.TradeCashId = tc.id; cic.ValidState = "Valid"; cic.Action = ClientCashInCashOut.系统操作_期权费; cic.Direction = ClientCashInCashOut.应收; cic.OptDate = DateTime.Now; cic.OptId = UserId; cic.OptName = UserName; //权利金默认为应收 已确认 cic.State = ClientCashInCashOut.已确认; cic.Number = UniqueTimeId.GetStr(); if (newtrade.TradeType == "远期") {//对于远期,期权费就是开仓总手续费,和买卖方向无关。 cic.Money = (-1) * newtrade.TradePrice; } else { cic.Money = newtrade.TradePrice * (newtrade.BuySell == "买入" ? 1 : -1); } cic.CurrencyCode = newtrade.SettlementCurrency; cic.TradeNumber = newtrade.TradeNumber; if (newtrade.TradeType == "收益互换" && newtrade.ParentTradeId > 0) { var parentTrade = DbContext.trade.Find(newtrade.ParentTradeId); cic.ParentTradeNumber = parentTrade.TradeNumber; } cic.IsGroup = newtrade.IsGroup; if (addClientCash) { DbContext.ClientCashInCashOut.Add(cic); } tc.Status = TradeCashStatusEnum.已执行; new TradeCashService(this).SaveTradeCashDetail(tc); } DbContext.SaveChanges(); // 追保规则-合约维度盯市:非互换交易(期权等)成交确认时,按计算保证金生成初始预付金资金记录(入金)。 // 客户维度盯市(null/1)不生成出入金,保证金只进 clientbalancedaily.PayableMargin(占用),维持现状。 // R4:资金来源是互换预付金腿上的录入项,期权等无腿交易无从选择授信,恒为现金(行为不变)。 var marginClient = DataCacheProvider.GetClientDataSource().GetData(newtrade.ClientId); if (marginClient != null && marginClient.MarginWatchRule == 0) { var initMargin = GetInitialMarginAmount(newtrade); if (initMargin > 0) { SaveSwapTradeClientCash(newtrade, initMargin, newtrade.TradeDate ?? DateTime.Now, 0, ClientCashInCashOut.系统操作_应付预付金); } } } /// /// 计算合约维度盯市客户成交时应生成的初始预付金金额: /// 交易绑定了预付金模板V2 → 名义本金(StockEqvNotional) × 初始率x("无预付金"规则算出0,不生成记录); /// 否则(老交易/期权)→ trade.InitialMargin。期权未放开V2绑定,恒走 InitialMargin。 /// public double GetInitialMarginAmount(trade td) { if (td == null) return 0; // 新交易(绑定了 V2 模板)→ 名义本金 × x bool boundV2 = DbContext.trade_margin_template.AsNoTracking().Any(x => x.TradeId == td.id); if (boundV2) { var valueDate = td.TradeDate ?? DateTime.Today; var rate = MarginTemplateV2RateHelper.GetTradeMarginRate(td.id, td.UnderlyingCode, td.UnderlyingInstrumentType, valueDate, DbContext); if (rate != null) { return Math.Abs((double)(rate.InitRate ?? 0m) * td.StockEqvNotional); } // 绑定了模板但取率失败(模板无效/规则不支持/明细无匹配)→ 兜底用 InitialMargin } // 老交易(未绑 V2)/期权 → trade.InitialMargin return Math.Abs(td.InitialMargin ?? 0); } /// /// 新版互换 期权费 /// matchDate=true 时 upsert 键追加 HappenDate(按结算日幂等):用于追加保证金等逐日增量记录, /// 每个结算日一条独立记录,避免单条累计值覆盖 + HappenDate 前移导致跨日差分窗口全额重复计入(BUG-03)。 /// /// /// public void SaveSwapTradeClientCash(trade swapTrade,double money, DateTime HappenDate,long positionId,string action= ClientCashInCashOut.系统操作_期权费, bool matchDate = false) { if (swapTrade is null) { throw new ArgumentNullException(nameof(swapTrade)); } if (money==0) { return; } var valueDate = valuedateBLL.ValueDate; var client = DataCacheProvider.GetClientDataSource().GetData(swapTrade.ClientId); var cic = DbContext.ClientCashInCashOut.FirstOrDefault(t => t.TradeId == swapTrade.id && t.ValidState != ConsGlobal.InValid && t.Action == action &&t.Deal==positionId && (!matchDate || t.HappenDate == HappenDate)); bool addClientCash = false; if (cic == null) { addClientCash = true; cic = new ClientCashInCashOut() { CreateDate = DateTime.Now, CreatorId = UserId, CreatorName = UserName }; cic.OptDate = DateTime.Now; } cic.HappenDate = HappenDate; cic.ClientId = swapTrade.ClientId; cic.ClientName = swapTrade.ClientName; cic.ClientNumber = client.Number; cic.TradeId = swapTrade.id; cic.ValidState = "Valid"; cic.Action = action; cic.Direction = ClientCashInCashOut.应收; cic.OptId = UserId; cic.OptName = UserName; cic.State = ClientCashInCashOut.已确认; cic.Number = UniqueTimeId.GetStr(); cic.Money = money; cic.CurrencyCode = swapTrade.SettlementCurrency; cic.TradeNumber = swapTrade.TradeNumber; cic.IsGroup = swapTrade.IsGroup; cic.Deal = positionId; if (addClientCash) { DbContext.ClientCashInCashOut.Add(cic); } DbContext.SaveChanges(); } /// /// 客户出入金操作 /// public ClientCashInCashOut SaveEntryexit(int? id, EntryExitReq req) { if (req is null) { throw new ArgumentNullException(nameof(req)); } if (req.Money >= 1000000000000) { throw new ServiceException("金额不能大于一万亿"); } if (req.Money < 0) { throw new ServiceException("金额不能小于零"); } if (req.HappenDate > DateTime.Now) { throw new ServiceException("出入金时间不能大于当前时间"); } ClientCashInCashOut r; var isAddNew = id == null || id == 0; if (isAddNew) { r = new ClientCashInCashOut { OptId = UserId, OptName = UserName, OptDate = DateTime.Now, CreatorId = UserId, CreatorName = UserName, CreateDate = DateTime.Now, State = "未确认" }; DbContext.ClientCashInCashOut.Add(r); } else { r = DbContext.ClientCashInCashOut.Find(id); if (r == null) { throw new ServiceException("数据未找到"); } // 更新操作人&操作时间 SetDBModelOpt(r); } var r_copy = r.Clone(); string comment = null; var diffs = new List(); if (r.State != "未确认") { if (r.Comments != req.Comments) { diffs.Add("备注"); r.Comments = req.Comments; } req.Money = req.Direction == "其他收入" || r.Money > 0 ? req.Money : (req.Money * -1); } else { req.Money = req.Direction == "其他支出" ? (req.Money * -1) : req.Money; diffs = GetDiffs(req, r); r.ClientId = req.ClientId; r.Direction = req.Direction; var client = ClientDataQueryService.GetClient(req.ClientId ?? 0, true); r.ClientName = client.Name; r.Money = req.Money; r.HappenDate = req.HappenDate; r.Comments = req.Comments; r.ClientNumber = client.Number; r.TradeId = req.Tradeid; r.Action = ClientCashInCashOut.人工操作_其他; r.OpenBank = null; r.OpenBankCard = null; r.OpenBankComments = null; r.OpenBankId = null; } if (isAddNew) { //新增编号 r.Number = UniqueTimeId.GetStr(); } var changecashs = DataChangeHelper.GetDataChanges(r_copy, r); comment = changecashs.ToJson(); if (r.State != "未确认") { var r_copyupdate = r.Clone(); r_copyupdate.Money = req.Money; r_copyupdate.Comments = req.Comments; if (req.Direction != null && req.Direction.Contains("其他")) { r_copyupdate.Direction = req.Direction; r_copyupdate.HappenDate = req.HappenDate; } changecashs = DataChangeHelper.GetDataChanges(r_copy, r_copyupdate); comment = changecashs.ToJson(); } if (comment == "[]" && diffs.Count() == 0) { return r; } if (req.OpenBankId == null || req.OpenBankId == 0) { r.OpenBankId = null; } DbContext.SaveChanges(); //排除一下只改备注的情况 if (r.State != "未确认" && changecashs.Count > 0 && !(changecashs.Count == 1 && changecashs[0][0] == "Comments")) { bool isOldupdate = false; if (DbContext.clientcashincashout_update.Where(x => x.ClientcashincashoutId == r.id && x.State == "修改待确认" && x.ValidState != "InValid").Any()) { var updateInValid = DbContext.clientcashincashout_update.Where(x => x.ClientcashincashoutId == r.id && x.State == "修改待确认" && x.ValidState != "InValid").ToList(); updateInValid.ForEach(x => x.ValidState = "InValid"); isOldupdate = true; } var clientcashincashout_Update = new clientcashincashout_update { OptId = UserId, OptName = UserName, OptDate = DateTime.Now, ClientcashincashoutId = r.id, OldMoney = r.Money ?? 0, NewMoney = req.Money ?? 0, OldDirection = r.Direction, NewDirection = req.Direction ?? r.Direction, OldHappenDate = r.HappenDate, NewHappenDate = req.HappenDate ?? r.HappenDate, ValidState = "Valid", State = "修改待确认" }; DbContext.clientcashincashout_update.Add(clientcashincashout_Update); ClientCashLog(r.id, "修改资金", comment, req.Explain); if (req.Tradeid > 0) { var trade = DbContext.trade.Find(req.Tradeid); SaveTradeOperationHistory(trade, isOldupdate ? "修改(修改待确认)资金" : "修改(已确认)资金"); } } else { if (id == 0 || id == null) { ClientCashLog(r.id, "新增资金"); if (req.Tradeid > 0) { var trade = DbContext.trade.Find(req.Tradeid); SaveTradeOperationHistory(trade, "添加其他资金"); } } else { if (diffs.Count == 1 && diffs[0] == "备注") { ClientCashLog(r.id, "修改备注", comment, req.Explain); } else { ClientCashLog(r.id, "修改资金", comment, req.Explain); } if (req.Tradeid > 0) { var trade = DbContext.trade.Find(req.Tradeid); SaveTradeOperationHistory(trade, "修改(未确认)资金"); } } } return r; } public void ClientCashLog(int CashId, string Type, string changes = null, string explain = null) { DbContext.clientcash_log.Add(new ClientCashLog { CashId = CashId, Changes = changes, OptType = Type, OptId = UserId, OptName = UserName, OptDate = DateTime.Now, Explain = explain }); DbContext.SaveChanges(); } private List GetDiffs(EntryExitReq newData, ClientCashInCashOut oldData) { var diffs = new List(); if (newData.ClientId != oldData.ClientId) { diffs.Add("客户"); } if (newData.Direction != oldData.Direction) { diffs.Add("方向"); } if (newData.HappenDate != oldData.HappenDate) { diffs.Add("发生日期"); } if (newData.Money != oldData.Money) { diffs.Add("金额"); } if (newData.OpenBankId != oldData.OpenBankId) { diffs.Add("银行卡"); } if (newData.Comments != oldData.Comments) { diffs.Add("备注"); } return diffs; } /// /// 客户出入金确认操作 /// /// public void ExcuteEntryExit(IEnumerable entryids) { var entrys = DbContext.ClientCashInCashOut.Where(e => e.ValidState != "InValid" && entryids.Contains(e.id)).ToList(); var clientIds = entrys.Select(t => t.ClientId).Distinct().ToList(); var tradeIds = entrys.Select(t => t.TradeId).Distinct().FirstOrDefault(); //获取客户信息 var clientList = DbContextFactory.GetClientDbContext(OptUser).client.Where(t => clientIds.Contains(t.id)).ToList(); var trade = DbContext.trade.Where(c => c.id == tradeIds).FirstOrDefault(); var dbtrade = trade.Clone(); //因为之前其他收入支出确认的时候 ClientCashInCashOut 没有加 trade_cash.id if (entrys.Where(x => x.TradeCashId == 0 && (x.State == "已确认" || x.State == "已结算")).Any()) { throw new ServiceException("未找该资金对应的交易资金的关联关系,无法进行该操作,请联系后台管理员:" + string.Join(",", entrys.Where(x => x.TradeCashId == 0 && (x.State == "已确认" || x.State == "已结算")).Select(x => x.Number).ToArray())); } List all_tradeids = new List(); all_tradeids.Add(trade.id); if (trade.IsGroup == 2) { all_tradeids.Add(trade.ParentTradeId); } using (var trans = BeginTransaction()) { if (entrys.Where(e => e.Action == ClientCashInCashOut.系统操作_期权费).Any()) { var delEodArr = DbContext.eod_trade.Where(O => all_tradeids.Contains(O.TradeId)); if (delEodArr.Any()) { DbContext.eod_trade.RemoveRange(delEodArr); } var codeList = DbContext.trade_contract_r.Where(O => all_tradeids.Contains(O.TradeId)); if (codeList.Any()) { DbContext.trade_contract_r.RemoveRange(codeList); } } else if (entrys.Where(e => e.Action == ClientCashInCashOut.系统操作_平仓费 || e.Action == ClientCashInCashOut.系统操作_行权费).Any()) { var minValue = entrys.Where(e => e.Action == ClientCashInCashOut.系统操作_平仓费 || e.Action == ClientCashInCashOut.系统操作_行权费).OrderBy(x => x.HappenDate ?? DateTime.MaxValue).FirstOrDefault(); var mindate = minValue.HappenDate.Value.AddDays(-1); var trade_cashs = DbContext.trade_cash.Where(x => all_tradeids.Contains(x.TradeId) && (x.Action == ClientCashInCashOut.系统操作_平仓费 || x.Action == ClientCashInCashOut.系统操作_行权费) && x.ValidState != ConsGlobal.InValid && !x.IsDeleted && (x.ValueDate > mindate && x.HappenedDate == null || x.HappenedDate > mindate)); var minValue_tc = trade_cashs.OrderBy(x => x.ValueDate).FirstOrDefault(); var delEodArr = DbContext.eod_trade.Where(O => all_tradeids.Contains(O.TradeId) && O.ValueDate >= minValue_tc.ValueDate); if (delEodArr.Any()) { DbContext.eod_trade.RemoveRange(delEodArr); } var tradecashid = trade_cashs.Select(x => x.id).ToHashSet(); var codeList = DbContext.trade_contract_r.Where(O => all_tradeids.Contains(O.TradeId) && tradecashid.Contains(O.TradeCashId ?? 0) && O.Type != ContractTypeEnum.Trade); if (codeList.Any()) { DbContext.trade_contract_r.RemoveRange(codeList); } } DbContext.SaveChanges(); // 系统操作_票息 修改 功能暂时禁掉 //var trade_cash_ids = entrys.Select(t => t.TradeCashId).Distinct().ToList(); //var autoCallObsercationList = DbContext.autocall_observation.Where(x => trade_cash_ids.Contains(x.CashId ?? 0) && x.CashId != null).ToList(); //if (entrys.Where(x => x.Action == ClientCashInCashOut.系统操作_票息).Any()) //{ // if (entrys.Where(x => x.Action == ClientCashInCashOut.系统操作_票息).Count() > autoCallObsercationList.Count()) // { // List number = new List(); // foreach (var item in entrys.Where(x => x.Action == ClientCashInCashOut.系统操作_票息)) // { // if (!autoCallObsercationList.Where(x => x.CashId == item.TradeCashId).Any()) // { // number.Add(item.Number); // } // } // throw new ServiceException("未找该资金对应的票息记录的关联关系,无法进行该操作,请联系后台管理员:" + string.Join(",", number)); // } //} var Parenttrade = DbContext.trade.Where(c => c.id == trade.ParentTradeId).FirstOrDefault(); var Parentdbtrade = Parenttrade?.Clone(); foreach (var e in entrys) { var clientCashInCashOut_clone = entrys.Where(x => x.id == e.id).FirstOrDefault().Clone(); if (e.State == "已确认" || e.State == "已结算") { var update = DbContext.clientcashincashout_update.Where(x => x.State == "修改待确认" && x.ValidState != ConsGlobal.InValid && x.ClientcashincashoutId == e.id).FirstOrDefault(); if (update == null) { continue; } var tc = DbContext.trade_cash.Where(x => x.id == e.TradeCashId).FirstOrDefault(); update.State = "已确认"; tc.Amount = update.NewMoney * -1; tc.OptId = UserId; tc.OptName = UserName; tc.OptDate = DateTime.Now; e.State = ClientCashInCashOut.已确认; e.Money = update.NewMoney; e.OptId = UserId; e.OptName = UserName; e.OptDate = DateTime.Now; if (!e.Direction.Contains("其他")) { var tradedetail = DbContext.trade_cash_detail.Where(x => x.TradeCashId == tc.id && x.Action == e.Action).FirstOrDefault(); tradedetail.Amount = update.NewMoney * -1; if (e.Action == ClientCashInCashOut.系统操作_期权费) { trade.TradePrice = TradeCalcHelper.GetSign(trade.BuySell) * update.NewMoney; trade.TradeSinglePrice = TradeHelper.GetTradeSinglePriceByTradePrice(trade.TradePrice, trade.OriginalNotional, trade.OriginalPrincipalSum, trade.BuySell, trade.TradeType, true); trade.PremiumRate = TradeHelper.GetPremiumRateByTradePrice(trade.TradePrice, trade.OriginalStockEqvNotional, trade.ParticipationRate, trade.OriginalPrincipalSum, trade.AnnualizeFactor, trade.BuySell, trade.TradeType, true); trade.OptId = UserId; trade.OptName = UserName; trade.OptDate = DateTime.Now; } else if (e.Action == ClientCashInCashOut.系统操作_平仓费 || e.Action == ClientCashInCashOut.系统操作_行权费) { tc.UnwindPrice = TradeHelper.GetTradeSinglePriceByTradePrice(tc.Amount, tc.UnwindNotional, trade.PrincipalSum(), trade.BuySell, trade.TradeType, false); tc.UnwindPricePercentRate = TradeHelper.GetPremiumRateByTradePrice(tc.Amount, tc.OriginalStockEqvNotional * tc.UnwindPercentRate, trade.ParticipationRate, trade.PrincipalSum(), trade.AnnualizeFactor, trade.BuySell, trade.TradeType, false); tc.UnwindPrice = tc.UnwindPrice * (trade.TradeType == "远期" || ConsTrade.HasMinusValueOptions.Contains(trade.TradeType) ? 1 : EodOperationBase.GetSign(trade.BuySell)); tc.UnwindPricePercentRate = tc.UnwindPricePercentRate * (trade.TradeType == "远期" || ConsTrade.HasMinusValueOptions.Contains(trade.TradeType) ? 1 : EodOperationBase.GetSign(trade.BuySell)); if (trade.IsGroup == 2) { var ParentTradeCash = DbContext.trade_cash.Where(x => x.id == tc.ParentTradeCashId).FirstOrDefault(); var childrenTradeCash = DbContext.trade_cash.Where(x => x.ParentTradeCashId == ParentTradeCash.id).ToList(); ParentTradeCash.Amount = childrenTradeCash.Sum(x => x.Amount); ParentTradeCash.UnwindPrice = ParentTradeCash.UnwindNotional != 0 ? ParentTradeCash.Amount / ParentTradeCash.UnwindNotional : 0; ParentTradeCash.UnwindPricePercentRate = TradeHelper.GetPremiumRateByTradeSinglePrice(ParentTradeCash.UnwindPrice, Parenttrade.SpotPrice); } } if (DbContext.autocall_observation.Where(x => x.CashId == e.TradeCashId).Any()) { var autocall_Observations = DbContext.autocall_observation.Where(x => x.CashId == e.TradeCashId).FirstOrDefault(); autocall_Observations.PaymentAmount = update.NewMoney * -1; } } else { tc.ValueDate = update.NewHappenDate.Value; tc.HappenedDate = update.NewHappenDate.Value; e.HappenDate = update.NewHappenDate.Value; e.Direction = update.NewDirection; } } else { var tc = new trade_cash { ValidState = "Valid", Status = TradeCashStatusEnum.已执行, ValueDate = e.HappenDate.Value, TradeId = e.TradeId ?? 0, TradeType = trade.BuySell, ExceciseType = "现金", Amount = e.Money.Value * -1, HappenedDate = e.HappenDate, OptId = UserId, OptName = UserName, OptDate = DateTime.Now, Action = ClientCashInCashOut.人工操作_其他 }; e.State = ClientCashInCashOut.已确认; e.OptId = UserId; e.OptName = UserName; e.OptDate = DateTime.Now; DbContext.trade_cash.Add(tc); DbContext.SaveChanges(); e.TradeCashId = tc.id; } ClientCashLog(e.id, "确定操作", null); DbContext.SaveChanges(); } if (trade.IsGroup == 2 && entrys.Where(e => e.Action == ClientCashInCashOut.系统操作_期权费).Any()) { var childrenTrade = DbContext.trade.Where(x => x.ParentTradeId == Parenttrade.id).ToList(); var childrenid = childrenTrade.Select(x => x.id).ToHashSet(); var childrenTradeCash = DbContext.trade_cash.Where(x => x.Action == ClientCashInCashOut.系统操作_期权费 && x.ValidState != ConsGlobal.InValid && !x.IsDeleted && childrenid.Contains(x.TradeId)).ToList(); var ParentTradeCash = DbContext.trade_cash.Where(x => x.Action == ClientCashInCashOut.系统操作_期权费 && x.ValidState != ConsGlobal.InValid && !x.IsDeleted && x.TradeId == Parenttrade.id).FirstOrDefault(); ParentTradeCash.Amount = childrenTradeCash.Sum(x => x.Amount); Parenttrade.TradePrice = childrenTradeCash.Sum(x => x.Amount) * (-EodOperationBase.GetSign(trade.BuySell)); Parenttrade.TradeSinglePrice = TradeHelper.GetTradeSinglePriceByTradePrice(Parenttrade.TradePrice, Parenttrade.OriginalNotional, Parenttrade.OriginalPrincipalSum, Parenttrade.BuySell, Parenttrade.TradeType, true); Parenttrade.PremiumRate = TradeHelper.GetPremiumRateByTradePrice(Parenttrade.TradePrice, Parenttrade.OriginalStockEqvNotional, Parenttrade.ParticipationRate, Parenttrade.OriginalPrincipalSum, Parenttrade.AnnualizeFactor, Parenttrade.BuySell, Parenttrade.TradeType, true); Parenttrade.OptId = UserId; Parenttrade.OptName = UserName; Parenttrade.OptDate = DateTime.Now; DbContext.SaveChanges(); var Parentchanges = DataChangeHelper.GetDataChanges(Parentdbtrade, Parenttrade); var comment = Parentchanges.ToJson(); SaveTradeOperationHistory(Parenttrade, "修改交易", comment); } DbContext.SaveChanges(); trans.Commit(); } var changes = DataChangeHelper.GetDataChanges(dbtrade, trade); if (changes.Count() > 0) { var comment = changes.ToJson(); SaveTradeOperationHistory(trade, "修改交易", comment); } SaveTradeOperationHistory(trade, "确认资金"); } /// /// 客户删除出入金操作 -- 交易上的其他资金 /// /// public void ExcuteEntryDele(int entryids) { var entry = DbContext.ClientCashInCashOut.Find(entryids); var trade = DbContext.trade.Where(c => c.id == entry.TradeId).FirstOrDefault(); //因为之前其他收入支出确认的时候 ClientCashInCashOut 没有加 trade_cash.id if (entry.TradeCashId == 0 && (entry.State == "已确认" || entry.State == "已结算")) { throw new ServiceException("未找该资金对应的交易资金的关联关系,无法进行该操作,请联系后台管理员"); } if (entry.State == "已确认" || entry.State == "已结算") { var tc = DbContext.trade_cash.Where(x => x.id == entry.TradeCashId).FirstOrDefault(); tc.ValidState = ConsGlobal.InValid; tc.OptId = UserId; tc.OptName = UserName; tc.OptDate = DateTime.Now; tc.IsDeleted = true; } var cash_update = DbContext.clientcashincashout_update.Where(x => x.ClientcashincashoutId == entry.id); DbContext.clientcashincashout_update.RemoveRange(cash_update); var cash_log = DbContext.clientcash_log.Where(x => x.CashId == entry.id); DbContext.clientcash_log.RemoveRange(cash_log); DbContext.ClientCashInCashOut.Remove(entry); var s = new Clientcashincashout_remove(); DbContext.Clientcashincashout_remove.Add(s); DbContext.Entry(s).CurrentValues.SetValues(entry); s.OptId = UserId; s.OptName = UserName; s.OptDate = DateTime.Now; s.CreatorId = UserId; s.CreatorName = UserName; s.CreateDate = DateTime.Now; DbContext.SaveChanges(); SaveTradeOperationHistory(trade, "删除其他资金"); } /// /// 拒绝出入金操作 /// /// /// public StringBuilder ClientCashInCashOutReject(IEnumerable entryids) { var sbmsg = new StringBuilder(); var entrys = DbContext.ClientCashInCashOut.Where(e => entryids.Contains(e.id)).ToList(); var entrys_update = DbContext.clientcashincashout_update.Where(e => entryids.Contains(e.ClientcashincashoutId) && e.State == "修改待确认").ToList(); entrys_update.ForEach(e => { e.State = "拒绝"; e.OptId = UserId; e.OptName = UserName; e.OptDate = DateTime.Now; }); foreach (var item in entrys) { var e_u = entrys_update.FirstOrDefault(x => x.ClientcashincashoutId == item.id); if (e_u != null) { var r_copy = item.Clone(); r_copy.Money = e_u.NewMoney; if (item.Direction.Contains("其他")) { r_copy.Direction = e_u.NewDirection; r_copy.HappenDate = e_u.NewHappenDate; } var changecashs = DataChangeHelper.GetDataChanges(r_copy, item); var comment = changecashs.ToJson(); ClientCashLog(item.id, "修改资金拒绝", comment); DbContext.SaveChanges(); } } if (entrys_update.Count() > 0) { DbContext.SaveChanges(); sbmsg.AppendLine("拒绝修改成功"); return sbmsg; } int? tradeId = 0; entrys.ForEach(e => { if (e.TradeId > 0) { tradeId = e.TradeId; } if (!ClientCashInCashOutReject(e)) { sbmsg.AppendLine($"{e.Number}方向为{e.Direction}不能拒绝"); } }); DbContext.SaveChanges(); if (sbmsg.Length > 0) { sbmsg.AppendLine("拒绝失败"); } else { sbmsg.AppendLine("拒绝成功"); if (tradeId > 0) { var trade = DbContext.trade.Find(tradeId); SaveTradeOperationHistory(trade, "拒绝其他资金"); } } return sbmsg; } private bool ClientCashInCashOutReject(ClientCashInCashOut e) { if (EntryExitBLL.EntryDirection_Menu.Contains(e.Direction) || ClientCashInCashOut.人工操作_其他.Equals(e.Action)) { e.State = "拒绝"; e.OptId = UserId; e.OptName = UserName; e.OptDate = DateTime.Now; ClientCashLog(e.id, "拒绝操作"); return true; } return false; } } }