using BaseOUDAL; using YLErp.BLL; using YLErp.BLL.Eod; using YLErp.Model; using YLErp.Model.Enum; using YLErp.Modules.ClientModule; using YLErp.Modules.SwapModule; using YLErp.Modules.TradeDalModule; namespace YLErp.Modules.TradeModule.DealModule { /// /// 交易审批操作 /// 来自:SetOpen /// public class TradeOpenService : TradeCashService { public TradeOpenService(YLBaseService baseService) : base(baseService) { } public TradeOpenService(OptUserInfo userInfo) : base(userInfo) { } /// /// 更新审批记录 /// public TradeOpenResult UpdateTradeProcessLog(TradeOpenReqModel req) { if (req is null) { throw new ArgumentNullException(nameof(req)); } try { if (string.IsNullOrEmpty(req.status)) { throw new ServiceException("参数不能为空:status"); } var td = DbContext.trade.Find(req.tradeId); if (td == null) { throw new ServiceException("没有找到该交易"); } if (td.TradeStatus != ConsTrade.审批中 && td.TradeStatus != ConsTrade.行权待复核 && td.TradeStatus != ConsTrade.平仓待复核 && td.TradeStatus != ConsTrade.互换待复核) { throw new ServiceException("该交易状态已变更,不能被审批,请先刷新页面"); } if (req.status == "pass") { return TradePass(req, td); } if (req.status == "reject") { return TradeReject(req, td); } throw new ServiceException("未知的参数值[status]:" + req.status); } catch (Exception ex) { LogFactory.GetLogger("交易审批").Error("提交交易审批", ex); throw; } } /// ///分组了结主交易 更新审批记录 /// public TradeOpenResult UpdateParentTradeProcessLog(TradeOpenReqModel req) { if (req is null) { throw new ArgumentNullException(nameof(req)); } try { if (string.IsNullOrEmpty(req.status)) { throw new ServiceException("参数不能为空:status"); } var td = DbContext.trade.Find(req.tradeId); if (td == null) { throw new ServiceException("没有找到该交易"); } if (td.TradeStatus != ConsTrade.审批中 && td.TradeStatus != ConsTrade.行权待复核 && td.TradeStatus != ConsTrade.平仓待复核 && td.TradeStatus != ConsTrade.互换待复核) { throw new ServiceException("该交易状态已变更,不能被审批,请先刷新页面"); } if (req.status == "pass") { return ParentTradePass(req, td); } if (req.status == "reject") { return ParentTradeReject(req, td); } throw new ServiceException("未知的参数值[status]:" + req.status); } catch (Exception ex) { LogFactory.GetLogger("交易审批").Error("提交交易审批", ex); throw; } } /// /// 放行交易 /// private TradeOpenResult TradePass(TradeOpenReqModel req, trade td) { var result = new TradeOpenResult(td); tradeBLL.SetFieldsByTradeType(td); if (td.TradeStatus != ConsTrade.行权待复核 && td.TradeStatus != ConsTrade.平仓待复核 && td.TradeStatus != ConsTrade.互换待复核 && !(req.ignoreMoneyCheck || td.IsGroup == 1) && !RealtimePnlCalc.TradeCanBeConfirm(td.ClientId, td, out var errorMsg)) { result.ErrorMsg = errorMsg; result.RetCode = TradeOpenRetCode.LackOfMoney; if (!PS.Config.Is申万) { var client = ClientDataQueryService.GetClient(td.ClientId); result.ErrorMsg = $"客户:{client?.Name},交易编号:{td.TradeNumber},{errorMsg}"; } return result; } //TODO 如果是审批组 var tradeProessQuery = TradeProcess(); var count = tradeProessQuery.Count(); if (count == 0 || td.ProcessOrderId == ProcessTradeLog.审批通过)//投资规模校验已经将数据设置为已通过 { req.comments = FormatCommentsWithRole(td.ProcessOrderId, req.comments); result.ChangeConfirmPath = SetTradeOpen(req, td); return result; } var orderIdCount = tradeProessQuery.Where(x => x.order == td.ProcessOrderId);//判断当前节点是否有分支 var nextOrder = tradeProessQuery.FirstOrDefault(x => x.order > td.ProcessOrderId); if (orderIdCount.Count()>1)//审批流程有分支情况 { nextOrder = tradeProessQuery.FirstOrDefault(x => x.order > td.ProcessOrderId && x.node == td.ProcessOrderBranch && x.approvalGroupId == 0); if (nextOrder==null)//已是子分支最后一个节点 { nextOrder = tradeProessQuery.FirstOrDefault(x => x.order > td.ProcessOrderId && x.node ==0);//寻找下一主分支节点 } } else if (nextOrder!=null&& nextOrder.approvalGroupId!=0)//下一节点有分支 { nextOrder = tradeProessQuery.FirstOrDefault(x => x.order > td.ProcessOrderId && x.node == td.ProcessOrderBranch&&x.approvalGroupId==0); } //else //{ // td.ProcessOrderBranch = 0; //} if (nextOrder==null) { req.comments = FormatCommentsWithRole(td.ProcessOrderId, req.comments); result.ChangeConfirmPath = SetTradeOpen(req, td); return result; } //----------------------------------------------- // 继续审批流转 //----------------------------------------------- var oldOrderId = td.ProcessOrderId; var formattedComments = FormatCommentsWithRole(oldOrderId, req.comments); td.ProcessOrderId = nextOrder.order; //client.ProcessStatus = "审批中"; td.ProcessOptDate = OptDate; td.OptId = UserId; td.OptName = UserName; td.OptDate = OptDate; DbContext.processtradelog.Add(new ProcessTradeLog { TradeId = td.id, ProcessType = "TradeProcess", ProcessStatus = ProcessTradeStatus.通过审批.ToString(), Log = req.comments, OptId = UserId, CreateTime = OptDate }); if (!req.notNeedOperationHistory) { AddTradeOperationHistoryAndSetParentTradeInfo(false, td, req.ignoreMoneyCheck ? "交易特批-交易审批同意" : "交易审批同意", formattedComments); } if (td.TradeType == "收益互换") { new SwapEventService(UserInfo).AddSwapEventDate(DateTime.Now.Date, td.id, (int)SwapEventTypeEnum.审批通过, "", 0, true, formattedComments); } DbContext.SaveChanges(); return result; } private TradeOpenResult ParentTradePass(TradeOpenReqModel req, trade td) { var tradeCashGroupActions = DbContext.trade_cash_group_action.Where(x => x.ParentTradeId == td.id && x.Status == "待完成"); if (!tradeCashGroupActions.Any()) { throw new ServiceException("未查询到该主交易的分组了结信息"); } var parentTradeCashId = tradeCashGroupActions.FirstOrDefault().ParentTradeCashId; var parentTradeCash = DbContext.trade_cash.Find(parentTradeCashId); var childrenTradeIds = tradeCashGroupActions.Select(s => s.TradeId).ToList(); var childrenTrades = DbContext.trade.Where(x => childrenTradeIds.Contains(x.id)).ToList(); var result = new TradeOpenResult(td); // 如果是审批组 var tradeProessQuery = TradeProcess(); var count = tradeProessQuery.Count(); if (count == 0) { SetParentTradeOpen(req, td, childrenTrades, parentTradeCash); return result; } var orderIdCount = tradeProessQuery.Where(x => x.order == td.ProcessOrderId);//判断当前节点是否有分支 var nextOrder = tradeProessQuery.FirstOrDefault(x => x.order > td.ProcessOrderId); if (orderIdCount.Count() > 1)//审批流程有分支情况 { nextOrder = tradeProessQuery.FirstOrDefault(x => x.order > td.ProcessOrderId && x.node == td.ProcessOrderBranch && x.approvalGroupId == 0); if (nextOrder == null)//已是子分支最后一个节点 { nextOrder = tradeProessQuery.FirstOrDefault(x => x.order > td.ProcessOrderId && x.node == 0);//寻找下一主分支节点 } } else if (nextOrder != null && nextOrder.approvalGroupId != 0)//下一节点有分支 { nextOrder = tradeProessQuery.FirstOrDefault(x => x.order > td.ProcessOrderId && x.node == td.ProcessOrderBranch && x.approvalGroupId == 0); } if (nextOrder == null) { SetParentTradeOpen(req, td, childrenTrades, parentTradeCash); return result; } //----------------------------------------------- // 继续审批流转 //----------------------------------------------- td.ProcessOrderId = nextOrder.order; td.ProcessOptDate = OptDate; td.OptId = UserId; td.OptName = UserName; td.OptDate = OptDate; childrenTrades.ForEach(x => { x.ProcessOrderId = nextOrder.order; x.ProcessOptDate = OptDate; x.OptId = UserId; x.OptName = UserName; x.OptDate = OptDate; }); DbContext.processtradelog.Add(new ProcessTradeLog { TradeId = td.id, ProcessType = "TradeProcess", ProcessStatus = ProcessTradeStatus.通过审批.ToString(), Log = req.comments, OptId = UserId, CreateTime = OptDate }); DbContext.SaveChanges(); return result; } /// /// 拒绝交易 /// private TradeOpenResult TradeReject(TradeOpenReqModel req, trade td) { var oldOrderId = td.ProcessOrderId; req.comments = FormatCommentsWithRole(oldOrderId, req.comments); td.ProcessOrderId = Convert.ToInt32(PStatusEnum.reject); td.ProcessOrderBranch = 0; //td.IsApproval = false; //行权或平仓审批拒绝时,状态变为提前终止拒绝 var swapTradeEventType = td.TradeStatus == ConsTrade.平仓待复核 ? (int)SwapEventTypeEnum.平仓 : (int)SwapEventTypeEnum.互换; if (td.TradeStatus == ConsTrade.行权待复核 || td.TradeStatus == ConsTrade.平仓待复核 || td.TradeStatus == ConsTrade.互换待复核) { td.TradeStatus = ConsTrade.提前终止拒绝; if (!req.notNeedOperationHistory) { AddTradeOperationHistoryAndSetParentTradeInfo(false, td, "提前终止拒绝", req.comments); } if (td.TradeType == "收益互换") { var swapEvent = DbContext.swap_event.Where(x => x.SwapTradeId == td.id && !x.Invalid && x.EventType == swapTradeEventType).OrderByDescending(o => o.id).FirstOrDefault(); if (swapEvent != null) { DbContext.swap_event.Remove(swapEvent); var swapFlowEvents = DbContext.swap_flow_event.Where(x => x.SwapTradeId == td.id && x.EventType == swapTradeEventType && x.EventDate == swapEvent.ValueDate); DbContext.swap_flow_event.RemoveRange(swapFlowEvents); } new SwapEventService(UserInfo).AddSwapEventDate(DateTime.Now.Date, td.id, (int)SwapEventTypeEnum.审批拒绝, "", 0, true, req.comments); } } else { td.TradeStatus = ConsTrade.已拒绝; if (!req.notNeedOperationHistory) { AddTradeOperationHistoryAndSetParentTradeInfo(false, td, "交易审批拒绝", req.comments); } if (td.TradeType == "收益互换") { new SwapEventService(UserInfo).AddSwapEventDate(DateTime.Now.Date, td.id, (int)SwapEventTypeEnum.审批拒绝, "", 0, true, req.comments); } } td.ProcessStatus = ProcessTradeStatus.已拒绝.ToString(); td.ProcessOptDate = OptDate; td.CheckStatus = 0; td.OptId = UserId; td.OptName = UserName; td.OptDate = OptDate; if (td.TradeType == "结构化交易") { var childTrades = DbContext.trade.Where(x => x.ParentTradeId == td.id).ToList(); childTrades.ForEach(x => { x.TradeStatus = td.TradeStatus; x.OptId = UserId; x.OptName = UserName; x.OptDate = OptDate; }); } DbContext.processtradelog.Add(new ProcessTradeLog { TradeId = req.tradeId, ProcessType = "TradeProcess", ProcessStatus = "拒绝审批", Log = req.comments, OptId = UserId, CreateTime = OptDate }); //增加现金交割交易记录,查询待审的现金交割记录(Invalid 这边为无效或是待审核交割记录) var tcId = DbContext.trade_cash.Where(t => t.TradeId == td.id && (t.Action == ClientCashInCashOut.系统操作_平仓费 || t.Action == ClientCashInCashOut.系统操作_互换) && t.ValidState == ConsGlobal.InValid && !t.IsDeleted).Select(O => O.id).OrderByDescending(x => x).FirstOrDefault(); var tcDetails = DbContext.trade_cash_detail.Where(O => O.TradeCashId == tcId); DbContext.trade_cash_detail.RemoveRange(tcDetails); DbContext.SaveChanges(); return new TradeOpenResult(td) { RetCode = TradeOpenRetCode.Success }; } /// ///分组了结主交易 拒绝交易 /// private TradeOpenResult ParentTradeReject(TradeOpenReqModel req, trade td) { var tradeCashGroupActions = DbContext.trade_cash_group_action.Where(x => x.ParentTradeId == td.id && x.Status == "待完成"); if (!tradeCashGroupActions.Any()) { throw new ServiceException("未查询到该主交易的分组了结信息"); } var parentTradeCashId = tradeCashGroupActions.FirstOrDefault().ParentTradeCashId; var parentTradeCash = DbContext.trade_cash.Find(parentTradeCashId); var childrenTradeIds = tradeCashGroupActions.Select(s => s.TradeId).ToList(); var childrenTrades = DbContext.trade.Where(x => childrenTradeIds.Contains(x.id)).ToList(); td.ProcessOrderId = Convert.ToInt32(PStatusEnum.reject); td.ProcessOrderBranch = 0; td.IsApproval = false; td.TradeStatus = ConsTrade.确认成交; td.ProcessStatus = ProcessTradeStatus.已拒绝.ToString(); td.ProcessOptDate = OptDate; td.CheckStatus = 0; td.OptId = UserId; td.OptName = UserName; td.OptDate = OptDate; //行权或平仓审批拒绝时,状态变为提前终止拒绝 if (td.TradeStatus == ConsTrade.行权待复核 || td.TradeStatus == ConsTrade.平仓待复核 || td.TradeStatus == ConsTrade.互换待复核) { if (!req.notNeedOperationHistory) { AddTradeOperationHistoryAndSetParentTradeInfo(false, td, "提前终止拒绝", req.comments); } } else { if (!req.notNeedOperationHistory) { AddTradeOperationHistoryAndSetParentTradeInfo(false, td, "交易审批拒绝", req.comments); } } childrenTrades.ForEach(x => { x.ProcessOrderId = td.ProcessOrderId; x.ProcessOrderBranch = td.ProcessOrderBranch; x.TradeStatus = td.TradeStatus; x.ProcessStatus = td.ProcessStatus; x.ProcessOptDate = OptDate; x.CheckStatus = td.CheckStatus; x.OptId = UserId; x.OptName = UserName; x.OptDate = OptDate; }); DbContext.processtradelog.Add(new ProcessTradeLog { TradeId = req.tradeId, ProcessType = "TradeProcess", ProcessStatus = "拒绝审批", Log = req.comments, OptId = UserId, CreateTime = OptDate }); childrenTradeIds.Add(req.tradeId); var delTradeCashes = DbContext.trade_cash.Where(O =>O.ParentTradeCashId==parentTradeCashId); var delTradeCashIds = delTradeCashes.Select(s=>s.id).ToList(); var clientCashs = DbContext.ClientCashInCashOut.Where(x=> delTradeCashIds.Contains(x.TradeCashId)); DbContext.trade_cash.RemoveRange(delTradeCashes); DbContext.trade_cash_group_action.RemoveRange(tradeCashGroupActions); DbContext.ClientCashInCashOut.RemoveRange(clientCashs); DbContext.SaveChanges(); return new TradeOpenResult(td) { RetCode = TradeOpenRetCode.Success }; } /// /// 设置交易开放 /// private string SetTradeOpen(TradeOpenReqModel req, trade td) { try { if (td.Warning) { new TradeDalService(OptUser).RollbackToBeforeSettle(td, SystemValueDate); } //设置成开户状态,写日志 td.ProcessOrderId = Convert.ToInt32(PStatusEnum.pass); td.TradeOldStatus = td.TradeStatus; td.CheckTradeUpdate = Convert.ToInt32(TradeCheckEnum.StatusOfNew); td.ProcessStatus = ProcessTradeStatus.通过审批.ToString(); td.ProcessOptDate = OptDate; td.OptId = UserId; td.OptName = UserName; td.OptDate = OptDate; td.IsApproval = false; //写入processtradelog DbContext.processtradelog.Add(new ProcessTradeLog { TradeId = req.tradeId, ProcessType = "TradeProcess", ProcessStatus = ProcessTradeStatus.通过审批.ToString(), Log = req.comments, OptId = UserId, CreateTime = OptDate }); new TradeConfirmService(this).EditReportStatus(td.id); var changeConfirmPath = string.Empty; if (td.TradeStatus == ConsTrade.行权待复核) { var tradeCashs = DbContext.trade_cash.Where(x => x.ValidState == "InValid" && !x.IsDeleted && x.Action == ClientCashInCashOut.系统操作_平仓费 && x.UnwindType == "部分行权" && x.TradeId == td.id); if (req.isPartialExercise || tradeCashs.Any()) { new TradeUnwindService(this).UnwindTrade(td, null, true, true); } else { ExecutionTradeCashInner(td, new TradeCashReq() { IsExpire = req.isExpire }, true); } if (!req.notNeedOperationHistory) { AddTradeOperationHistoryAndSetParentTradeInfo(false, td, "行权审批同意", req.comments); } DbContext.SaveChanges(); } else if (td.TradeStatus == ConsTrade.平仓待复核) { if (td.TradeType == "收益互换") { //new TradeUnwindService(this).ApproveUnwindSwapTrade(td); new SwapDealService(this).ApproveSwapTrade(td, (int)SwapEventTypeEnum.平仓); } else { new TradeUnwindService(this).UnwindTrade(td, null, true); } if (!req.notNeedOperationHistory) { AddTradeOperationHistoryAndSetParentTradeInfo(false, td, "平仓审批同意", req.comments); } DbContext.SaveChanges(); } else if (td.TradeStatus == ConsTrade.互换待复核) { // new TradeUnwindService(this).ApproveSwapTrade(td); new SwapDealService(this).ApproveSwapTrade(td,(int)SwapEventTypeEnum.互换); if (!req.notNeedOperationHistory) { AddTradeOperationHistoryAndSetParentTradeInfo(false, td, "互换审批同意", req.comments); } DbContext.SaveChanges(); } else if (td.TradeStatus == ConsTrade.审批中) { td.TradeStatus = ConsTrade.确认成交; if (td.TradeType=="收益互换") { SwapTradeService swapTradeService = new SwapTradeService(this); new SwapEventService(UserInfo).AddSwapEventDate(DateTime.Now.Date, td.id, (int)SwapEventTypeEnum.审批通过, "", 0, true, req.comments); new TradeConfirmService(UserInfo).SwapTradeConfirm(td, "确认交易",false, optlog: "手工操作"); } //组合交易(非互换) if (td.IsGroup == 1) { //删掉trade_check相关的复核数据 new TradeCheckService(this).DeleteTradeCheck(td.id); new TradeCashService(this).SaveGroupOpenTradeCash(td); //if (td.TradeType == "收益互换") //{ // var subtrades = DbContext.trade.Where(t => t.ParentTradeId == td.id).ToArray(); // foreach (var item in subtrades) // { // item.TradeOldStatus = item.TradeStatus; // item.TradeStatus = ConsTrade.确认成交; // //删掉trade_check相关的复核数据 // new TradeCheckService(this).DeleteTradeCheck(item.id); // new ClientCashInCashOutService(this).SaveClientCashInCashOut(item); // } //} } //结构化交易(牛市熊市价差期权等等)或者多空组合互换交易 else if (td.TradeType == "结构化交易") { var subtrades = DbContext.trade.Where(t => t.ParentTradeId == td.id).ToArray(); foreach (var item in subtrades) { item.TradeOldStatus = item.TradeStatus; item.TradeStatus = ConsTrade.确认成交; //删掉trade_check相关的复核数据 new TradeCheckService(this).DeleteTradeCheck(item.id); new ClientCashInCashOutService(this).SaveClientCashInCashOut(item); } } else { //删掉trade_check相关的复核数据 new TradeCheckService(this).DeleteTradeCheck(td.id); new ClientCashInCashOutService(this).SaveClientCashInCashOut(td); } if (!req.notNeedOperationHistory) { AddTradeOperationHistoryAndSetParentTradeInfo(false, td, req.ignoreMoneyCheck ? "交易特批-交易审批同意" : "交易审批同意", req.comments); } DbContext.SaveChanges(); //生成变更确认书 if (PS.Config.TradeElement.IsGenerateAmendDoc) { changeConfirmPath = new ChangeConfirmBookGenerator(this).GenerateChangeConfirmBook(td.id, out _); } } return changeConfirmPath; } catch (Exception ex) { LogFactory.GetLogger("交易审批").Error("设置审批状态出错", ex); throw; } } /// /// 设置交易开放 /// private void SetParentTradeOpen(TradeOpenReqModel req, trade td,List childrenTrades,trade_cash parentTradeCash) { try { parentTradeCash.ValidState = ConsGlobal.Valid; if (td.Warning) { new TradeDalService(OptUser).RollbackToBeforeSettle(td, SystemValueDate); } //设置成开户状态,写日志 td.ProcessOrderId = Convert.ToInt32(PStatusEnum.pass); td.TradeOldStatus = td.TradeStatus; td.CheckTradeUpdate = Convert.ToInt32(TradeCheckEnum.StatusOfNew); td.ProcessStatus = ProcessTradeStatus.通过审批.ToString(); td.ProcessOptDate = OptDate; td.OptId = UserId; td.OptName = UserName; td.OptDate = OptDate; td.IsApproval = false; td.TradeAmount -= (parentTradeCash.UnwindTradeAmount ?? 0); td.Notional -= (parentTradeCash.UnwindNotional ?? 0); td.StockEqvNotional -= (td.OriginalStockEqvNotional * parentTradeCash.UnwindPercentRate ?? 0); td.UnWindNotional = parentTradeCash.UnwindNotional; td.UnWindDate = parentTradeCash.ValueDate; td.FinalPrice = parentTradeCash.FinalPrice; if (td.TradeStatus == ConsTrade.平仓待复核&& !req.notNeedOperationHistory) { AddTradeOperationHistoryAndSetParentTradeInfo(false, td, "平仓审批同意", req.comments); } else if (td.TradeStatus == ConsTrade.行权待复核 && !req.notNeedOperationHistory) { AddTradeOperationHistoryAndSetParentTradeInfo(false, td, "行权审批同意", req.comments); } else { if (!req.notNeedOperationHistory) { AddTradeOperationHistoryAndSetParentTradeInfo(false, td, req.ignoreMoneyCheck ? "交易特批-交易审批同意" : "交易审批同意", req.comments); } } //写入processtradelog DbContext.processtradelog.Add(new ProcessTradeLog { TradeId = req.tradeId, ProcessType = "TradeProcess", ProcessStatus = ProcessTradeStatus.通过审批.ToString(), Log = req.comments, OptId = UserId, CreateTime = OptDate }); if (parentTradeCash.UnwindType == "全部平仓") { td.TradeStatus = "已平仓"; } else if (parentTradeCash.UnwindType == "全部行权"|| parentTradeCash.UnwindType == "到期行权") { td.TradeStatus = "已执行"; } else if (parentTradeCash.UnwindType == "到期") { td.TradeStatus = "已到期"; } else { td.TradeStatus = ConsTrade.确认成交; } var childrenTradeCashs = DbContext.trade_cash.Where(x=> x.ParentTradeCashId== parentTradeCash.id).ToList(); childrenTrades.ForEach(x => { if (x.Warning) { new TradeDalService(OptUser).RollbackToBeforeSettle(x, SystemValueDate); } x.ProcessOrderId = Convert.ToInt32(PStatusEnum.pass); x.TradeOldStatus = td.TradeOldStatus; x.CheckTradeUpdate = Convert.ToInt32(TradeCheckEnum.StatusOfNew); x.ProcessStatus = ProcessTradeStatus.通过审批.ToString(); x.ProcessOptDate = OptDate; x.OptId = UserId; x.OptName = UserName; x.OptDate = OptDate; var tradCash = childrenTradeCashs.Where(n => n.TradeId == x.id).OrderByDescending(o=>o.id).FirstOrDefault(); new TradeConfirmService(this).EditReportStatus(x.id); tradCash.ValidState = "Valid"; if (parentTradeCash.UnwindType.Contains("到期")) { var tradeCashReq = new TradeCashReq() { ValueDate = x.UnWindDate, TradeId = x.id, TradeAmount = x.TradeAmount, Notional = x.Notional, UnwindFee = tradCash.Amount, Amount = tradCash.Amount, UnwindTradeAmount = tradCash.UnwindTradeAmount, UnwindNotional = (tradCash.UnwindTradeAmount ?? 0) * (x.CountRatio ?? 1), UnwindPercentRate = tradCash.UnwindPercentRate ?? 0, UnwindStockEqvNotional = tradCash.UnwindStockEqvNotional, CallPut = x.OptionType, ExceciseType = "现金", FinalPrice = tradCash.FinalPrice, UnwindType = tradCash.UnwindType }; new TradeCashService(this).ExecutionTradeCash(tradeCashReq); } else { new TradeUnwindService(this).UnwindTrade(x, null, true); } if (x.TradeStatus == ConsTrade.平仓待复核)//子交易复核只有平仓待复核 { if (!req.notNeedOperationHistory) { AddTradeOperationHistoryAndSetParentTradeInfo(false, x, "平仓审批同意", req.comments); } } else { if (!req.notNeedOperationHistory) { AddTradeOperationHistoryAndSetParentTradeInfo(false, x, req.ignoreMoneyCheck ? "交易特批-交易审批同意" : "交易审批同意", req.comments); } } if(td.TradeStatus != "确认成交") { x.TradeStatus = td.TradeStatus; } }); //存黑箱主交易ClientCashInCashOut需要赋值0 //TradeCash在下面FinishGroupTradeCash里会根据子交易重新统计赋值 parentTradeCash.Amount = 0; new ClientCashinCashoutBLL(this).CloseTrade_ClientCashInCashOutSave(td, parentTradeCash, parentTradeCash.ValueDate); DbContext.SaveChanges(); new TradeUnwindService(this).FinishGroupTradeCash(parentTradeCash.id); } catch (Exception ex) { LogFactory.GetLogger("交易审批").Error("设置审批状态出错", ex); throw; } } private string GetRoleNameByOrderId(int orderId) { var node = DbContext.approvalprocess .FirstOrDefault(x => x.processType == "TradeProcess" && x.order == orderId); if (node == null) return null; return new ErpBaseContext().Roles .Where(r => r.Id == node.roleId) .Select(r => r.Name) .FirstOrDefault(); } private string FormatCommentsWithRole(int orderId, string comments) { var roleName = GetRoleNameByOrderId(orderId); if (string.IsNullOrEmpty(roleName)) return comments ?? string.Empty; return $"【角色:{roleName}】{comments}"; } } /// /// 审批操作请求Model /// public class TradeOpenReqModel { public int tradeId; public string status; public string comments; public bool ignoreMoneyCheck; public bool notNeedOperationHistory; public bool isPartialExercise; public bool isExpire = false; } /// /// 审批操作结果 /// public class TradeOpenResult { /// /// 结果代码 /// public TradeOpenRetCode RetCode; public int TrialDataId; /// /// 错误信息 /// public string ErrorMsg; /// /// 提示信息 /// public string TipMsg; /// /// 变更确认书路径 /// public string ChangeConfirmPath { get; set; } public trade Trade; public TradeOpenResult(trade trade) { Trade = trade ?? throw new ArgumentNullException(nameof(trade)); RetCode = TradeOpenRetCode.None; } } /// /// 审批操作结果代码 /// public enum TradeOpenRetCode { None = -1, /// /// 成功 /// Success = 0, /// /// 缺少资金 /// LackOfMoney, /// /// 限额试算失败 /// QuotaTrialError, /// /// 资金状况 /// FundStatus, /// /// 风控预警二次确认 /// RiskWarning, /// /// 无审核权限 /// NoRight } }