Files
zszq-trs/YLErpDAL/Modules/TradeModule/ClientCashInCashOutService.cs
T

861 lines
40 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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
{
/// <summary>
/// 交易资金保存服务
/// 交易状态发生变化时调用检查对应资金对资金进行修改
/// </summary>
public class ClientCashInCashOutService : TradeServiceBase
{
public ClientCashInCashOutService(YLBaseService baseService) : base(baseService)
{
}
public ClientCashInCashOutService(OptUserInfo userInfo) : base(userInfo)
{
}
/// <summary>
/// 交易状态发生变化时调用检查对应资金对资金进行修改
/// </summary>
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.系统操作_应付预付金);
}
}
}
/// <summary>
/// 计算合约维度盯市客户成交时应生成的初始预付金金额:
/// 交易绑定了预付金模板V2 → 名义本金(StockEqvNotional) × 初始率x"无预付金"规则算出0,不生成记录);
/// 否则(老交易/期权)→ trade.InitialMargin。期权未放开V2绑定,恒走 InitialMargin。
/// </summary>
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);
}
/// <summary>
/// 新版互换 期权费
/// matchDate=true 时 upsert 键追加 HappenDate(按结算日幂等):用于追加保证金等逐日增量记录,
/// 每个结算日一条独立记录,避免单条累计值覆盖 + HappenDate 前移导致跨日差分窗口全额重复计入(BUG-03)。
/// </summary>
/// <param name="swapTrade"></param>
/// <exception cref="ArgumentNullException"></exception>
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();
}
/// <summary>
/// 客户出入金操作
/// </summary>
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<string>();
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<string> GetDiffs(EntryExitReq newData, ClientCashInCashOut oldData)
{
var diffs = new List<string>();
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;
}
/// <summary>
/// 客户出入金确认操作
/// </summary>
/// <param name="entryids"></param>
public void ExcuteEntryExit(IEnumerable<int> 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<int> all_tradeids = new List<int>();
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<string> number = new List<string>();
// 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, "确认资金");
}
/// <summary>
/// 客户删除出入金操作 -- 交易上的其他资金
/// </summary>
/// <param name="entryids"></param>
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, "删除其他资金");
}
/// <summary>
/// 拒绝出入金操作
/// </summary>
/// <param name="entryids"></param>
/// <returns></returns>
public StringBuilder ClientCashInCashOutReject(IEnumerable<int> 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;
}
}
}