857 lines
40 KiB
C#
857 lines
40 KiB
C#
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(占用),维持现状。
|
||
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>
|
||
/// 新版互换 期权费
|
||
/// </summary>
|
||
/// <param name="swapTrade"></param>
|
||
/// <exception cref="ArgumentNullException"></exception>
|
||
public void SaveSwapTradeClientCash(trade swapTrade,double money, DateTime HappenDate,long positionId,string action= ClientCashInCashOut.系统操作_期权费)
|
||
{
|
||
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);
|
||
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;
|
||
}
|
||
}
|
||
}
|