Files
zszq-trs/YLErpDAL/Modules/ClientModule/ClientCashInCashOutDataService.cs
T
2025-04-23 13:58:26 +08:00

1549 lines
65 KiB
C#

using BaseOUDAL;
using Newtonsoft.Json.Linq;
using System.Data.SqlTypes;
using System.Text;
using System.Text.RegularExpressions;
using YLErp.Abstract;
using YLErp.BLL;
using YLErp.BLL.EodSettlement;
using YLErp.Commons;
using YLErp.Configuration;
using YLErp.Core.Helpers;
using YLErp.DBModels.Enums;
using YLErp.Helpers;
using YLErp.Model;
using YLErp.Model.Enum;
using YLErp.Modules.DataCacheModule;
using YLErp.Modules.ReportModule;
using YLErp.Modules.SwapModule;
using YLErp.Office;
using YLErp.Office.Converters;
namespace YLErp.Modules.ClientModule
{
/// <summary>
/// 客户出入金服务
/// </summary>
public class ClientCashInCashOutDataService : YLBaseService
{
public ClientCashInCashOutDataService(YLBaseService baseService) : base(baseService)
{
}
public ClientCashInCashOutDataService(OptUserInfo userInfo) : base(userInfo)
{
}
public HandleResult ImportClientBalanceGap(Stream stream, bool IsMargin)
{
var rows = new YLErp.Commons.ExcelHelper().ExcelToDataTable(stream, null, true);
var clientNumber = string.Empty;
ClientBalanceGapReq record;
var records = new List<ClientBalanceGapReq>();
var rowNum = 0;
for (var i = 0; i < rows.Rows.Count; i++)
{
rowNum = i + 1;
record = new ClientBalanceGapReq();
for (var j = 0; j < rows.Columns.Count; j++)
{
switch (rows.Columns[j].ColumnName)
{
case "客户编号":
clientNumber = rows.Rows[i][j].ToString();
break;
case "客户名称":
record.ClientName = rows.Rows[i][j].ToString();
break;
case "调整日期":
if (DateTime.TryParse(rows.Rows[i][j].ToString(), out var date))
{
record.ValueDate = date;
}
else
{
return "第" + rowNum + "行结束时间格式不对,导入失败";
}
break;
case "出金入金":
if (string.IsNullOrWhiteSpace(rows.Rows[i][j].ToString()) || IsMargin)
{
record.NetFund = 0;
}
else
if (double.TryParse(rows.Rows[i][j].ToString(), out var netFund))
{
record.NetFund = netFund;
}
else
{
return "第" + rowNum + "行出金入金格式不对,导入失败";
}
break;
case "成交收支":
if (string.IsNullOrWhiteSpace(rows.Rows[i][j].ToString()) || IsMargin)
{
record.OptionPremium = 0;
}
else
if (double.TryParse(rows.Rows[i][j].ToString(), out var optionPremium))
{
record.OptionPremium = optionPremium;
}
else
{
return "第" + rowNum + "行成交收支格式不对,导入失败";
}
break;
case "了结收支":
if (string.IsNullOrWhiteSpace(rows.Rows[i][j].ToString()) || IsMargin)
{
record.SettlementBalance = 0;
}
else
if (double.TryParse(rows.Rows[i][j].ToString(), out var settlementBalance))
{
record.SettlementBalance = settlementBalance;
}
else
{
return "第" + rowNum + "行了结收支格式不对,导入失败";
}
break;
case "票息":
if (string.IsNullOrWhiteSpace(rows.Rows[i][j].ToString()) || IsMargin)
{
record.Coupon = 0;
}
else
if (double.TryParse(rows.Rows[i][j].ToString(), out var coupon))
{
record.Coupon = coupon;
}
else
{
return "第" + rowNum + "行票息格式不对,导入失败";
}
break;
case "互换收支":
if (string.IsNullOrWhiteSpace(rows.Rows[i][j].ToString()) || IsMargin)
{
record.SwapBalance = 0;
}
else
if (double.TryParse(rows.Rows[i][j].ToString(), out var swapBalance))
{
record.SwapBalance = swapBalance;
}
else
{
return "第" + rowNum + "行互换收支格式不对,导入失败";
}
break;
case "其他收支":
if (string.IsNullOrWhiteSpace(rows.Rows[i][j].ToString()) || IsMargin)
{
record.OtherFund = 0;
}
else
if (double.TryParse(rows.Rows[i][j].ToString(), out var otherFund))
{
record.OtherFund = otherFund;
}
else
{
return "第" + rowNum + "行其他收支格式不对,导入失败";
}
break;
case "期末结存":
if (string.IsNullOrWhiteSpace(rows.Rows[i][j].ToString()) || IsMargin)
{
record.ToDayRemainFund = 0;
}
else
if (double.TryParse(rows.Rows[i][j].ToString(), out var toDayRemainFund))
{
record.ToDayRemainFund = toDayRemainFund;
}
else
{
return "第" + rowNum + "行期末结存格式不对,导入失败";
}
break;
case "授信额度":
if (string.IsNullOrWhiteSpace(rows.Rows[i][j].ToString()) || IsMargin)
{
record.Credit = 0;
}
else
if (double.TryParse(rows.Rows[i][j].ToString(), out var credit))
{
record.Credit = credit;
}
else
{
return "第" + rowNum + "行授信额度格式不对,导入失败";
}
break;
case "应付了交易结款":
if (string.IsNullOrWhiteSpace(rows.Rows[i][j].ToString()) || IsMargin)
{
record.ClosedTradePayableFund = 0;
}
else
if (double.TryParse(rows.Rows[i][j].ToString(), out var closedTradePayableFund))
{
record.ClosedTradePayableFund = closedTradePayableFund;
}
else
{
return "第" + rowNum + "行应付了交易结款格式不对,导入失败";
}
break;
case "应付存续交易款":
if (string.IsNullOrWhiteSpace(rows.Rows[i][j].ToString()) || IsMargin)
{
record.PositionTradePayableFund = 0;
}
else
if (double.TryParse(rows.Rows[i][j].ToString(), out var positionTradePayableFund))
{
record.PositionTradePayableFund = positionTradePayableFund;
}
else
{
return "第" + rowNum + "行应付存续交易款格式不对,导入失败";
}
break;
case "追保金额":
if (string.IsNullOrWhiteSpace(rows.Rows[i][j].ToString()) || IsMargin)
{
record.MarginByPayableMargin = 0;
}
else
if (double.TryParse(rows.Rows[i][j].ToString(), out var marginByPayableMargin))
{
record.MarginByPayableMargin = marginByPayableMargin;
}
else
{
return "第" + rowNum + "行追保金额格式不对,导入失败";
}
break;
case "应付资金总额":
if (string.IsNullOrWhiteSpace(rows.Rows[i][j].ToString()) || IsMargin)
{
record.PayableFund = 0;
}
else
if (double.TryParse(rows.Rows[i][j].ToString(), out var payableFund))
{
record.PayableFund = payableFund;
}
else
{
return "第" + rowNum + "行应付资金总额格式不对,导入失败";
}
break;
case "实现盈亏":
if (string.IsNullOrWhiteSpace(rows.Rows[i][j].ToString()) || IsMargin)
{
record.WinLoss = 0;
}
else
if (double.TryParse(rows.Rows[i][j].ToString(), out var winLoss))
{
record.WinLoss = winLoss;
}
else
{
return "第" + rowNum + "行实现盈亏格式不对,导入失败";
}
break;
case "持仓盈亏":
if (string.IsNullOrWhiteSpace(rows.Rows[i][j].ToString()) || IsMargin)
{
record.PositionPnl = 0;
}
else
if (double.TryParse(rows.Rows[i][j].ToString(), out var positionPnl))
{
record.PositionPnl = positionPnl;
}
else
{
return "第" + rowNum + "行持仓盈亏格式不对,导入失败";
}
break;
case "持仓市值":
if (string.IsNullOrWhiteSpace(rows.Rows[i][j].ToString()) || IsMargin)
{
record.PositionPv = 0;
}
else
if (double.TryParse(rows.Rows[i][j].ToString(), out var positionPv))
{
record.PositionPv = positionPv;
}
else
{
return "第" + rowNum + "行持仓市值格式不对,导入失败";
}
break;
case "预付金占用":
if (double.TryParse(rows.Rows[i][j].ToString(), out var payableMargin))
{
record.PayableMargin = payableMargin;
}
else
{
return "第" + rowNum + "行预付金格式不对,导入失败";
}
break;
default:
break;
}
}
if (string.IsNullOrWhiteSpace(record.ClientName))
{
if (string.IsNullOrWhiteSpace(clientNumber))
{
return "第" + rowNum + "行客户编码和名称都为空,导入失败";
}
else
{
var client = DataCacheProvider.GetClientDataSource().AsQueryable().Where(o => o.Number == clientNumber).FirstOrDefault();
if (client != null)
{
record.ClientName = client.Name;
}
else
{
return "第" + rowNum + "行客户不存在,导入失败";
}
}
}
else
{
var client = ClientDataQueryService.GetClient(record.ClientName);
if (client == null)
{
return "第" + rowNum + "行客户不存在,导入失败";
}
}
record.IsImportOuterMargin = IsMargin;
records.Add(record);
}
if (records.Count() > 0)
{
foreach (var item in records)
{
ClientBalanceGapApi(item);
}
}
else
{
return "未在文件中找到记录";
}
return HandleResult.Success;
}
public void ClientBalanceGapApi(ClientBalanceGapReq req)
{
if (req == null)
{
throw new ServiceException("数据不能为空");
}
if (req.ClientName == null)
{
throw new ServiceException("客户名称不能为空");
}
if (req.ValueDate == DateTime.MinValue)
{
throw new ServiceException("结束日期不能为空");
}
var Clieninfo = ClientDataQueryService.GetClient(req.ClientName);
if (Clieninfo == null)
{
throw new ServiceException("客户不存在");
}
if (req.ToDayRemainFund == null || req.ToDayRemainFund == 0)
{
req.ToDayRemainFund = req.NetFund + req.OptionPremium + req.SettlementBalance + req.Coupon + req.SwapBalance + req.OtherFund;
}
if (req.PayableFund == null || req.PayableFund == 0)
{
req.PayableFund = req.ClosedTradePayableFund + req.PositionTradePayableFund + req.MarginByPayableMargin;
}
var IsClientbalanceGap = DbContext.ClientBalanceGap.Where(c => c.ClientId == Clieninfo.id && c.ValueDate == req.ValueDate && c.IsImportOuterMargin == req.IsImportOuterMargin).FirstOrDefault();
if (IsClientbalanceGap == null)
{
IsClientbalanceGap = new ClientBalanceGap();
DbContext.ClientBalanceGap.Add(IsClientbalanceGap);
}
IsClientbalanceGap.ClientId = Clieninfo.id;
IsClientbalanceGap.ValueDate = req.ValueDate;
IsClientbalanceGap.NetFund = req.NetFund;
IsClientbalanceGap.OptionPremium = req.OptionPremium;
IsClientbalanceGap.SettlementBalance = req.SettlementBalance;
IsClientbalanceGap.Coupon = req.Coupon;
IsClientbalanceGap.SwapBalance = req.SwapBalance;
IsClientbalanceGap.OtherFund = req.OtherFund;
IsClientbalanceGap.ToDayRemainFund = req.ToDayRemainFund;
IsClientbalanceGap.Credit = req.Credit;
IsClientbalanceGap.ClosedTradePayableFund = req.ClosedTradePayableFund;
IsClientbalanceGap.PositionTradePayableFund = req.PositionTradePayableFund;
IsClientbalanceGap.MarginByPayableMargin = req.MarginByPayableMargin;
IsClientbalanceGap.PayableFund = req.PayableFund;
IsClientbalanceGap.WinLoss = req.WinLoss;
IsClientbalanceGap.PositionPnl = req.PositionPnl;
IsClientbalanceGap.PositionPv = req.PositionPv;
IsClientbalanceGap.PayableMargin = req.PayableMargin;
IsClientbalanceGap.IsImportOuterMargin = req.IsImportOuterMargin;
DbContext.SaveChanges();
}
/// <summary>
/// 客户抵押品确认操作
/// </summary>
/// <param name="entryids"></param>
public void ExcuteClientCashInCashOutProduc(IEnumerable<int> entryids)
{
var entrys = DbContext.clientcashincashout_product.Where(e => entryids.Contains(e.id) && !ClientCashInCashOut.已确认.Equals(e.OptStatus)).OrderBy(t => t.OptDate).ToList();
var clientIds = entrys.Select(t => t.ClientId).Distinct().ToList();
//当前抵押且执行的抵押品记录(包含抵押执行状态的记录和赎回待执行或者赎回拒绝的记录)
var entrysExecutedProduct = DbContext.clientcashincashout_product.Where(t => (ClientCashInCashOut.已确认.Equals(t.OptStatus) && Clientcashincashout_productStatusEnum.抵押.ToString().Equals(t.Status))
|| (t.OptStatus != ClientCashInCashOut.已确认 && Clientcashincashout_productStatusEnum.赎回.ToString().Equals(t.Status))).ToList();
//获取客户信息
var clientList = DbContextFactory.GetClientDbContext(OptUser).client.Where(t => clientIds.Contains(t.id)).ToList();
foreach (var e in entrys)
{
//当前执行的出入金标的即期价格
e.SpotPrice = DataCacheProvider.GetUnderlyingDataSource().GetData(e.UnderlyingId ?? 0)?.Price;
//查看客户是否被冻结需要解冻
if (Clientcashincashout_productStatusEnum.抵押.ToString().Equals(e.Status))
{
var client = clientList.FirstOrDefault(t => t.id == e.ClientId);
//判断是否为冻结状态
if (client.PendingMarginCallPayment == 1)
{
//查看当前客户可用资金是否符合出金条件
var clientbalance = ClientBalanceUtility.GetClientBanlances(new List<int> { e.ClientId }, DateTime.MinValue, DateTime.Now.Date).FirstOrDefault();
//如果入金量大于追保金额则更改冻结状态为正常状态
if (!clientbalance.IsMargin(e.SpotPrice * e.ProductAmount * e.Rate ?? 0.0))
{
client.PendingMarginCallPayment = 0;
}
}
}
e.ExcuteDate = DateTime.Now;
e.ExcuteId = UserId;
e.ExcuteName = UserName;
e.OptStatus = ClientCashInCashOut.已确认;
e.OptId = UserId;
e.OptName = UserName;
e.OptDate = DateTime.Now;
DbContext.SaveChanges();
if (Clientcashincashout_productStatusEnum.抵押.ToString().Equals(e.Status))
{
entrysExecutedProduct.Add(e);
}
else
{
entrysExecutedProduct.Remove(e);
}
}
}
/// <summary>
/// 客户出入金Api
/// </summary>
public ClientCashInCashOut SaveEntryexitApi(SaveEntryexitApiReq req)
{
if (!req.ClientId.HasValue)
{
throw new ServiceException("ClientId参数错误");
}
var exsist = new ClientDataService(OptUser).ExsistById(req.ClientId.Value);
if (!exsist)
{
throw new ServiceException("ClientId参数错误,未找到对应客户");
}
var Bankcard = ClientDataQueryService.GetBankCard(req.ClientId.Value, req.OpenBankCard);
if (Bankcard == null)
{
throw new ServiceException("银行账号未找到");
}
var model = new ClientCashInCashOut
{
ClientId = req.ClientId,
ClientName = req.ClientName,
Direction = req.Direction,
Money = req.Money,
OpenBankId = Bankcard.id,
OpenBankCard = Bankcard.Card,
HappenDate = req.HappenDate,
Comments = req.Comments,
CashFlag = req.CashFlag,
Action = "API"
};
return SaveEntryexit(0, model);
}
/// <summary>
/// 客户出入金操作
/// </summary>
public ClientCashInCashOut SaveEntryexit(int? id, ClientCashInCashOut req)
{
if (req is null)
{
throw new ArgumentNullException(nameof(req));
}
if (!req.Money.HasValue)
{
throw new ServiceException("金额必须填写");
}
if (!req.HappenDate.HasValue || req.HappenDate == DateTime.MinValue)
{
throw new ServiceException("出入金时间必须填写");
}
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;
double? originalMoney = 0;
var isARAP = req.Direction == "应收" || req.Direction == "应付";
var aRAPFlag = req.Direction == "应收" ? 1 : -1;
string comment = null;
if (isAddNew)
{
r = new ClientCashInCashOut
{
CreatorId = UserId,
CreatorName = UserName,
CreateDate = DateTime.Now,
OptId = UserId,
OptName = UserName,
OptDate = DateTime.Now,
State = "未确认"
};
DbContext.ClientCashInCashOut.Add(r);
}
else
{
r = DbContext.ClientCashInCashOut.Find(id);
if (r == null)
{
throw new ServiceException("数据未找到");
}
originalMoney = r.ClientId == req.ClientId && r.Direction == "出金" ? r.Money : 0;
}
var r_copy = r.Clone();
var diffs = new List<string>();
if (r.State != "未确认")
{
if (r.Comments != req.Comments)
{
diffs.Add("备注");
r.Comments = req.Comments;
}
//req.Money = (req.Direction == "其他支出" ? -1 : 1) * req.Money;
}
else
{
if (string.IsNullOrEmpty(req.Direction))
{
throw new ServiceException("新增资金记录,参数Direction不能为空");
}
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.Direction == "其他支出" ? -1 : 1) * req.Money;
r.HappenDate = req.HappenDate;
r.OpenBankCard = req.OpenBankCard;
r.OpenBankId = req.OpenBankId;
r.Comments = req.Comments;
r.ClientNumber = client.Number;
r.Action = req.Action;
r.CashFlag = req.CashFlag;
r.CurrencyCode = req.CurrencyCode;
r.cash_type = req.cash_type;
r.ValidState = ConsGlobal.Valid;
}
if (isARAP)
{
r.Direction = ClientCashInCashOut.应收;
r.Money *= aRAPFlag;
}
//应收为正,实收为负
//应付为负,实付为正
else if (req.Direction == "实收预付金" || req.Direction == "实收权利金")
{
r.Money = -r.Money;
}
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;
}
#region 出金申请时进行验资
if ("出金".Equals(r.Direction) && valuedateBLL.SystemDate.SpecialOperateForCashOut != 1)
{
//查看当前客户可用资金是否符合出金条件
var clientbalance = ClientBalanceUtility.GetClientBanlances(new List<int> { r.ClientId.Value }, DateTime.MinValue, DateTime.Now.Date).FirstOrDefault();
// 如果余额为 null,则视为无可用资金
if (clientbalance == null)
{
clientbalance = new YLErp.Models.ClientSettleBalance();
}
//当日可取现金
var availableFund = clientbalance.DesirableFund;
//对于0.999999999情况的数据做下处理
var realAvailableFund = Math.Round((availableFund + (originalMoney ?? 0.0)) * Math.Pow(10, 8)) / Math.Pow(10, 8);
//如果出金大于可用资金(修改操作时需要算差价)则抛出错误
if (Math.Abs(r.Money ?? 0.0) > realAvailableFund)
{
var msg = "添加出金失败,客户:" + r.ClientName + " 出金:" + r.Money + " 实际可取出资金:" +
(Math.Floor(realAvailableFund * 100) / 100).ToString("0.00") + ";";
throw new ServiceException(msg);
}
if (r.Money <= clientbalance.VmFundSum)
{
// 出金金额小于等于 追保账户金额
r.cash_type = CashTypeEnum.追保账户.ToString();
}
else if (clientbalance.VmFundSum==0)
{
r.cash_type = CashTypeEnum.初保账户.ToString();
}
else
{
// 出金金额大于 追保账户金额,首先处理 VM 部分
r.cash_type = CashTypeEnum.追保账户.ToString();
var newMoney = r.Money - clientbalance.VmFundSum;
r.Money = clientbalance.VmFundSum;
var newR = r.Clone();
newR.id = 0;
newR.Money = newMoney;
newR.cash_type = CashTypeEnum.初保账户.ToString();
DbContext.ClientCashInCashOut.Add(newR);
}
}
#endregion
if (r.Direction != "出金" && r.Direction != "入金")
{
r.OpenBank = null;
r.OpenBankCard = null;
r.OpenBankComments = null;
r.OpenBankId = null;
}
DbContext.SaveChanges();
if (r.State != "未确认" && changecashs.Count > 0 && !(changecashs.Count == 1 && changecashs[0][0] == "Comments"))
{
}
else
{
if (id == 0 || id == null)
{
ClientCashLog(r.id, "新增资金");
}
else
{
if (diffs.Count == 1 && diffs[0] == "备注")
{
ClientCashLog(r.id, "修改备注", comment, req.Explain);
}
else
{
ClientCashLog(r.id, "修改资金", comment, req.Explain);
}
}
}
return r;
}
private bool CheckClientCashOut(int ClientId, double Money, string CurrencyCode)
{
var client = DataCacheProvider.GetClientDataSource().GetData(ClientId);
if (client != null && client.BoundSide == BoundSideEnum.南向)
{
var clientCashes = new EntryExitBLL().getClientCash(ClientId);
if (clientCashes.TryGetValue(CurrencyCode, out var remains))
{
if (remains >= Money)
{
return true;
}
}
return false;
}
return true;
}
public ClientCashInCashOut saveClientCashInOutComments(int? id, EntryExitReq req)
{
if (req is null)
{
throw new ArgumentNullException(nameof(req));
}
var r = DbContext.ClientCashInCashOut.Find(id);
if (r == null)
{
throw new ServiceException("数据未找到");
}
var r_copy = r.Clone();
r.Comments = req.Comments;
DbContext.SaveChanges();
var changecashs = DataChangeHelper.GetDataChanges(r_copy, r);
var comment = changecashs.ToJson();
ClientCashLog(r.id, "修改备注", comment, req.Explain);
return r;
}
private List<string> GetDiffs(ClientCashInCashOut 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 || newData.OpenBankCard != oldData.OpenBankCard)
{
diffs.Add("银行卡");
}
if (newData.Comments != oldData.Comments)
{
diffs.Add("备注");
}
return diffs;
}
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();
}
/// <summary>
/// 客户出入金确认操作
/// </summary>
/// <param name="entryids"></param>
public void ExcuteEntryExit(IEnumerable<int> entryids, IKafkaProduce kafkaProduce)
{
var entrys = DbContext.ClientCashInCashOut.Where(e => e.ValidState != "InValid" && entryids.Contains(e.id) && !ClientCashInCashOut.已确认.Equals(e.State)).OrderBy(t => t.OptDate).ToList();
var clientIds = entrys.Select(t => t.ClientId).Distinct().ToList();
//获取客户信息
var clientList = DbContextFactory.GetClientDbContext(OptUser).client.Where(t => clientIds.Contains(t.id)).ToList();
if (entrys.Any(s => s.ApprovalProcess > 0))
{
throw new ServiceException("无法对状态为审批中的资金记录进行确认,请到资金审批页面进行资金审批操作!");
}
var outCashProcess = GetOutCashProcess();
SwapConsumerService swapConsumerService = new SwapConsumerService(UserInfo);
if (kafkaProduce != null)
{
swapConsumerService.SetKafKaProduce(kafkaProduce);
}
foreach (var e in entrys)
{
if (e.Direction == "出金" && outCashProcess.Count > 0)
{
e.State = ClientCashInCashOut.审批中;
e.ApprovalProcess = 1;
}
else
{
ExcuteEntryExit(e, clientList);
e.State = ClientCashInCashOut.已确认;
}
e.ApprovalDate= DateTime.Now;
e.OptId = UserId;
e.OptName = UserName;
e.OptDate = DateTime.Now;
ClientCashLog(e.id, "确定操作");
DbContext.SaveChanges();
//if (kafkaProduce!=null&& e.State== ClientCashInCashOut.已确认&&(e.Direction=="入金"|| e.Direction == "出金"))
//{
// Task.Run(() =>
// {
// swapConsumerService.PushCashToHT(e.id, null) ;
// });
//}
}
}
public bool ExcuteEntryExit(int clientList, string auditComments = "")
{
var entry = DbContext.ClientCashInCashOut.FirstOrDefault(c => c.id == clientList);
if (entry == null)
{
throw new ServiceException("资金记录不存在");
}
var res = ExcuteEntryExit(entry, null);
var notCanOperateState = new List<string>() { ClientCashInCashOut.已确认, ClientCashInCashOut.拒绝, ClientCashInCashOut.已结算 };
if (notCanOperateState.Contains(entry.State))
{
throw new ServiceException("已确认、拒绝、已结算的记录不能再次确认");
}
entry.State = ClientCashInCashOut.已确认;
entry.OptId = UserId;
entry.OptName = UserName;
entry.OptDate = DateTime.Now;
entry.ApprovalProcess = Convert.ToInt32(PStatusEnum.pass);
entry.ApprovalDate = DateTime.Now;
ClientCashLog(entry.id, "确定操作", auditComments);
DbContext.SaveChanges();
return res;
}
private bool ExcuteEntryExit(ClientCashInCashOut e, IEnumerable<Client> clientList)
{
//查看客户是否被冻结需要解冻
if ("入金".Equals(e.Direction) || ("应收".Equals(e.Direction) && ClientCashInCashOut.人工操作_预付金.Equals(e.Action)))
{
var client = clientList != null ? clientList.FirstOrDefault(t => t.id == e.ClientId)
: DbContextFactory.GetClientDbContext(OptUser).client.Find(e.ClientId ?? 0);
if (client == null)
{
throw new ServiceException("客户信息不存在");
}
//判断是否为冻结状态
if (client.PendingMarginCallPayment == 1)
{
var clientbalance = ClientBalanceUtility.GetClientBanlances(new List<int> { e.ClientId.Value }, DateTime.MinValue, DateTime.Now.Date).FirstOrDefault();
//如果入金量大于追保金额则更改冻结状态为正常状态
if (!clientbalance.IsMargin(e.Money ?? 0.0))
{
client.PendingMarginCallPayment = 0;
}
}
}
//else if ((("出金".Equals(e.Direction) && PS.Config.Company != Configuration.CompanyEnum.中金) || ("应付".Equals(e.Direction) && ClientCashInCashOut.人工操作_预付金.Equals(e.Action))) && valuedateBLL.SystemDate.SpecialOperateForCashOut != 1 && PS.Config.Company != Configuration.CompanyEnum.中金)
//{
// //查看当前客户可用资金是否符合出金条件
// var clientbalance = ClientBalanceUtility.GetClientBanlances(new List<int> { e.ClientId.Value }, DateTime.MinValue, DateTime.Now.Date).FirstOrDefault();
// //当日可取现金
// var availableFund = clientbalance == null ? 0 : clientbalance.DesirableFund;
// //对于0.999999999情况的数据做下处理
// var realAvailableFund = Math.Round((availableFund + (e.Money??0)) * Math.Pow(10, 8)) / Math.Pow(10, 8);
// //如果当前出金金额大于可用资金(不扣除冻结出金部分)则抛出错误
// if (Math.Abs(e.Money ?? 0) > realAvailableFund)
// {
// if ("出金".Equals(e.Direction))
// {
// throw new ServiceException($"部分确认错误 客户:{e.ClientName},出金:{e.Money},实际可取出资金:{realAvailableFund:0.00};");
// }
// throw new ServiceException($"部分确认错误,客户:{e.ClientName},应付预付金:{Math.Abs(e.Money ?? 0)},实际可取出资金:{realAvailableFund:0.00};");
// }
//}
return true;
}
/// <summary>
/// 客户出入金拒绝操作
/// </summary>
public StringBuilder ClientCashInCashOutReject(IEnumerable<int> entryids)
{
var sbmsg = new StringBuilder();
var entrys = DbContext.ClientCashInCashOut.Where(e => entryids.Contains(e.id)).ToList();
if (entrys.Any(s => s.ApprovalProcess > 0))
{
throw new ServiceException("无法对状态为审批中的资金记录进行拒绝,请到资金审批页面进行资金审批操作!");
}
entrys.ForEach(e =>
{
if (!ClientCashInCashOutReject(e))
{
sbmsg.AppendLine($"{e.Number}方向为{e.Direction}不能拒绝");
}
});
DbContext.SaveChanges();
if (sbmsg.Length > 0)
{
sbmsg.AppendLine("拒绝失败");
}
else
{
sbmsg.AppendLine("拒绝成功");
}
return sbmsg;
}
public bool ClientCashInCashOutReject(int entryid)
{
var entry = DbContext.ClientCashInCashOut.FirstOrDefault(e => e.id == entryid);
if (entry == null)
{
throw new ServiceException("资金记录不存在");
}
var res = ClientCashInCashOutReject(entry);
if (!res)
{
throw new ServiceException($"{entry.Number}方向为{entry.Direction}不能拒绝");
}
DbContext.SaveChanges();
return res;
}
private bool ClientCashInCashOutReject(ClientCashInCashOut e, string auditComments = "")
{
if (EntryExitBLL.EntryDirection_Menu.Contains(e.Direction) || ClientCashInCashOut.人工操作_预付金.Equals(e.Action))
{
var notCanOperateState = new List<string>() { ClientCashInCashOut.已确认, ClientCashInCashOut.拒绝, ClientCashInCashOut.已结算 };
if (notCanOperateState.Contains(e.State))
{
throw new ServiceException("已确认、拒绝、已结算的记录不能再次拒绝");
}
e.State = "拒绝";
e.OptId = UserId;
e.OptName = UserName;
e.OptDate = DateTime.Now;
e.ApprovalProcess = Convert.ToInt32(PStatusEnum.reject);
e.ApprovalDate = DateTime.Now;
ClientCashLog(e.id, "拒绝操作", auditComments);
return true;
}
return false;
}
public List<ClientCashInCashOut> GetClientCashInCashOut(EntryExitReq req)
{
var query = from db in DbContext.ClientCashInCashOut where db.ValidState != "InValid" select db;
if (req != null)
{
if (req.ClientNameList != null)
{
query = query.Where(O => req.ClientNameList.Contains(O.ClientName));
}
if (req.ClientNumberList != null)
{
query = query.Where(O => req.ClientNumberList.Contains(O.ClientNumber));
}
if (req.HappenDateStart != DateTime.MinValue && req.HappenDateStart != SqlDateTime.MinValue.Value)
{
if (req.HappenDateStart == req.HappenDateEnd)
{
query = query.Where(O => req.HappenDateStart == O.HappenDate);
}
else
{
query = query.Where(O => req.HappenDateStart <= O.HappenDate);
}
}
if (req.HappenDateEnd != DateTime.MinValue &&
req.HappenDateEnd != SqlDateTime.MinValue.Value &&
req.HappenDateEnd != req.HappenDateStart)
{
query = query.Where(O => req.HappenDateEnd >= O.HappenDate);
}
if (req.DirectionList != null)
{
query = query.Where(O => req.DirectionList.Contains(O.Direction));
}
if (req.ActionList != null)
{
query = query.Where(O => req.ActionList.Contains(O.Action));
}
if (req.MoneyStart != null)
{
if (req.MoneyStart == req.MoneyEnd)
{
query = query.Where(O => req.MoneyStart == O.Money);
}
else
{
query = query.Where(O => req.MoneyStart <= O.Money);
}
}
if (req.MoneyEnd != null && req.MoneyStart != req.MoneyEnd)
{
query = query.Where(O => req.MoneyEnd >= O.Money);
}
if (req.StateList != null)
{
query = query.Where(O => req.StateList.Contains(O.State));
}
if (req.TradeNumberList != null)
{
query = query.Where(O => req.TradeNumberList.Contains(O.TradeNumber));
}
}
return query.ToList();
}
/// <summary>
/// 获取出金审批流程
/// </summary>
/// <returns></returns>
public List<approvalprocess> GetOutCashProcess()
{
return DbContext.approvalprocess.Where(x => x.processType == "OutCashProcess").OrderBy(o => o.order).ToList();
}
/// <summary>
/// 出金审批
/// </summary>
/// <param name="req"></param>
public void AuditClientOutCash(ClientCashAuditReq req)
{
var entry = DbContext.ClientCashInCashOut.FirstOrDefault(e => e.id == req.id);
if (entry == null)
{
throw new ServiceException("资金记录不存在");
}
if (entry.State != ClientCashInCashOut.审批中)
{
throw new ServiceException("资金记录状态不正确");
}
if (req.status == "reject")
{
ClientCashInCashOutReject(entry, req.auditComment);
return;
}
var outCashProcess = GetOutCashProcess();
var nextProcess = outCashProcess.Where(x => x.order > entry.ApprovalProcess).FirstOrDefault(); ;
if (nextProcess != null)
{
entry.ApprovalProcess = nextProcess.order;
entry.OptId = UserId;
entry.OptName = UserName;
entry.OptDate = DateTime.Now;
ClientCashLog(entry.id, "审批通过", req.auditComment);
DbContext.SaveChanges();
}
else
{
ExcuteEntryExit(req.id, req.auditComment);
}
}
/// <summary>
/// 审批撤回
/// </summary>
/// <param name="id"></param>
/// <exception cref="ServiceException"></exception>
public void GoBackAuditClientCash(int id)
{
var entry = DbContext.ClientCashInCashOut.FirstOrDefault(e => e.id == id);
if (entry == null)
{
throw new ServiceException("资金记录不存在");
}
var outCashProcess = GetOutCashProcess();
if (entry.State != ClientCashInCashOut.审批中 || entry.ApprovalProcess > 1)
{
throw new ServiceException("资金记录状态不正确");
}
entry.State = ClientCashInCashOut.未确认;
entry.OptId = UserId;
entry.OptName = UserName;
entry.OptDate = DateTime.Now;
entry.ApprovalProcess = 0;
ClientCashLog(entry.id, "审批", "撤回审批");
DbContext.SaveChanges();
}
/// <summary>
/// 下载出金付款单
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
/// <exception cref="ServiceException"></exception>
public string DownloadOutEntryexit(int id)
{
var entry = DbContext.ClientCashInCashOut.FirstOrDefault(e => e.id == id);
if (entry == null)
{
throw new ServiceException("资金记录不存在");
}
var templatePath = Path.Combine(OtcAppContext.AppDocsPath, "导出模板", "出金付款单导出模板.docx");
if (!File.Exists(templatePath))
{
throw new ServiceException($"找不到模板信息");
}
var clientDbContext = DbContextFactory.GetClientDbContext(OptUser);
var client = clientDbContext.client.Find(entry.ClientId);
ClientBankCard bankcard = null;
if (entry.OpenBankId > 0)
{
bankcard = clientDbContext.bankcard.FirstOrDefault(x => x.ApprovalOrder < 1 && x.id == entry.OpenBankId && x.ClientId == client.id && x.ValidState != "InValid");
}
else
{
bankcard = clientDbContext.bankcard.FirstOrDefault(x => x.ApprovalOrder < 1 && x.ClientId == client.id && x.ValidState != "InValid");
}
if (bankcard == null)
{
throw new ServiceException($"客户{client.Name}对应的银行帐户信息未找到");
}
var fileName = $"出金付款单{entry.Number}.docx";
var outputFilePath = GetOutputFilePath(fileName);
var modelDic = GetOutEntryexitDic(entry, client, bankcard);
var varDic = new JsonVarDic(modelDic);
OfficeFileConverter.ConvertByUsingDocTemplate(templatePath, outputFilePath, varDic, false);
var absolutePath = TradeContractHelper.GetAbsolutePath(outputFilePath, fileName);
var appDocsPath = OtcAppContext.AppDocsPath;
return $"/App_Docs{absolutePath.Replace(appDocsPath, "").Replace(appDocsPath, "").Replace("\\", "/")}";
}
/// <summary>
/// 获取 账户明细信息
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
public ClientDingShiReport GetClientReportData(int id)
{
var entry = DbContext.ClientCashInCashOut.FirstOrDefault(e => e.id == id);
if (entry == null)
{
throw new ServiceException("资金记录不存在");
}
var clientId = entry.ClientId ?? 0;
var report = new ClientDingShiReport
{
client = DataCacheProvider.GetClientDataSource().GetData(clientId),
ClientBank = new ClientDBContext().bankcard.Where(x => x.ApprovalOrder < 1 && x.ClientId == clientId && x.ValidState != "InValid").ToList(),
OptUserInfo = this.UserInfo
};
var toDate = DateTime.Now;
report.ReportEnd = toDate;
var clientBalance = ClientBalanceUtility.GetClientBanlances(new List<int> { clientId }, DateTime.MinValue, report.ReportEnd, IsClientBalanceGap: false, IsGetOuterMarginGap: true, ParentFlag: false).FirstOrDefault();
report.FundReportModel = new FundReportModel()
{
LastDayRemainFund = clientBalance?.LastDayRemainFund ?? 0,
LastDayRemainFundWithProduct = clientBalance?.LastDayRemainFundWithProduct ?? 0,
CashInCashOutChange = clientBalance?.NetFund ?? 0,
CashInChange = clientBalance?.InFund ?? 0,
CashOutChange = clientBalance?.OutFund ?? 0,
CashInCashOutOther = clientBalance?.OtherFund ?? 0,
CashInCashOutProductChange = clientBalance?.CashInCashOutProductChange ?? 0,
OptionPremium = clientBalance?.OptionPremium ?? 0,
OptionPremiumSwap = clientBalance?.OptionPremiumSwap ?? 0,
SettlementBalance = clientBalance?.SettlementBalance ?? 0,
UnwindBalance = clientBalance?.UnwindBalance ?? 0,
ExerciseBalance = clientBalance?.ExerciseBalance ?? 0,
SwapBalance = clientBalance?.SwapBalance ?? 0,
Coupon = clientBalance?.Coupon ?? 0,
TodayRemianFund = clientBalance?.AmountFund ?? 0,
TodayRemianFundProduct = clientBalance?.AmountFundWithProduct ?? 0,
GuaranteesTotalAmount = clientBalance?.GuaranteesTotalAmount ?? 0,
WorstCastClientPayable = clientBalance?.MinusPayableMarginTotal ?? 0,
AvailableFund = clientBalance?.AvailableAmount ?? 0,
TotalMargin = clientBalance?.TotalMarginTotal,
Credit = clientBalance?.TotalCredit ?? 0,
CreditRatio = clientBalance?.CreditUsed ?? 0,
Margin = clientBalance?.MarginByPayableMarginTotal ?? 0,
Amount = (PS.Config.IsPVRounded ? clientBalance?.RoundedTotalAmountTotal : clientBalance?.TotalAmountTotal) ?? 0,
TotalPnl = PS.Config.IsPVRounded ? (decimal)(clientBalance?.RoundedPositionPnl ?? 0) : (decimal)(clientBalance?.PositionPnl ?? 0),
PositionPremiumNetCash = clientBalance?.PositionPremiumNetCash ?? 0,
SellTradePrice = clientBalance?.SellTradePrice,
LastDayPositionPremiumNetCash = clientBalance?.LastDayPositionPremiumNetCash ?? 0,
WinLoss = clientBalance?.WinLoss ?? 0,
ClosedTradeFundGap = clientBalance?.ClosedTradeFundGap ?? 0,
ClosedTradePayableFund = clientBalance?.ClosedTradePayableFundTotal ?? 0,
PositionTradePayableFund = clientBalance?.PositionTradePayableFundTotal ?? 0,
DesirableFund = clientBalance?.DesirableFundTotal ?? 0,
PayableFund = clientBalance?.PayableFundTotal ?? 0,
PositionPv = PS.Config.IsPVRounded ? (clientBalance?.RoundedPositionPv ?? 0) : (clientBalance?.PositionPv ?? 0),
PrepaymentAmount = clientBalance?.PrepaymentAmount,
PositionPnl = PS.Config.IsPVRounded ? (clientBalance?.RoundedPositionPnl ?? 0) : (clientBalance?.PositionPnl ?? 0),
TotalNetSettlement = clientBalance?.TotalNetSettlementTotal ?? 0,
ClientSellPositionPnl = clientBalance?.ClientSellPositionPnl,
FreezePremium = clientBalance?.FreezePremium
};
if (PS.Config.Company == CompanyEnum.润和)
{
report.FundReportModel.SettlementBalance += report.FundReportModel.SwapBalance;
report.FundReportModel.CreditOccupy = Math.Min(report.FundReportModel.Credit ?? 0, Math.Max((report.FundReportModel.WorstCastClientPayable - report.FundReportModel.TodayRemianFund) ?? 0, 0));
report.FundReportModel.DesirableFund = Math.Max(report.FundReportModel.AvailableFund ?? 0, 0);
report.FundReportModel.AvailableFund = report.FundReportModel.AvailableFund + report.FundReportModel.Credit;
}
var desc = DBCacheManager.Single.GetStr(CacheTable.DingShiDesc);
var descList = Regex.Split(desc, "</p>", RegexOptions.IgnoreCase).Where(x => !string.IsNullOrWhiteSpace(x)).ToList();
var newDescList = new List<string>();
descList.ForEach(x =>
{
x = Regex.Replace(x, "<[^>]+>", "");
x = Regex.Replace(x, "&[^;]+;", "");
newDescList.Add(x);
});
report.descList = newDescList;
report.desc = desc;
return report;
}
/// <summary>
/// 获取 账户信息pdf文件
/// </summary>
/// <param name="report"></param>
/// <param name="html"></param>
/// <returns></returns>
public string GenerateReportPDF(ClientDingShiReport report, string html)
{
var pdfHelper = new PdfHelper();
var sourcePath = OtcAppContext.MapPath("~/App_Docs/TradeMarket");
if (!Directory.Exists(sourcePath))
{
Directory.CreateDirectory(sourcePath);
}
var clientName = report.client.Name;
var fileName = $"资金结算报告_{clientName}_{report.ReportEnd:yyyy-MM-dd}";
var sourceFileName = Path.Combine(sourcePath, $"{fileName}.pdf");
pdfHelper.ToPDFFile(html, sourceFileName, true);
return sourceFileName;
}
/// <summary>
/// 付款单基础数据填充
/// </summary>
/// <param name="entry"></param>
/// <param name="client"></param>
/// <param name="bankcard"></param>
/// <returns></returns>
private Dictionary<string, JToken> GetOutEntryexitDic(ClientCashInCashOut entry, Client client, ClientBankCard bankcard)
{
var dic = new Dictionary<string, JToken>();
FormatToDictHelper.FormatToDict("发生时间", entry.HappenDate, dic);
FormatToDictHelper.FormatToDict("金额", entry.Money, dic);
dic["客户银行账户名称"] = bankcard.ClientName;
if (!string.IsNullOrEmpty(entry.OpenBankCard))
{
dic["客户银行账户账号"] = entry.OpenBankCard;
}
else
{
dic["客户银行账户账号"] = bankcard.Card;
}
dic["客户银行账户开户行"] = bankcard.Bank;
dic["客户名称"] = client.Name;
dic["客户编号"] = client.Number;
dic["备注"] = entry.Comments;
return dic;
}
/// <summary>
/// 获取生成文档的输出路径(物理路径)
/// </summary>
private string GetOutputFilePath(string fileName)
{
var folder = Path.Combine(OtcAppContext.AppDocsPath, "contractdoc\\output");
if (!Directory.Exists(folder))
{
Directory.CreateDirectory(folder);
}
return Path.Combine(folder, fileName);
}
/// <summary>
/// 资金审批查询
/// </summary>
/// <param name="req"></param>
/// <returns></returns>
public SearchListResult<EntryExitApprovalQueryRes> EntryexitApprovalQuery(EntryExitApprovalQueryReq req)
{
var predicate = PredicateBuilder.Create<ClientCashInCashOut>(n => n.ValidState != ConsGlobal.InValid && n.IsGroup != 1 && n.ApprovalProcess > 0);
if (!string.IsNullOrEmpty(req.DirectionType))
{
predicate = predicate.And(x => x.Direction == req.DirectionType);
}
if (req.ClientIdsInt.Any())
{
predicate = predicate.And(x => req.ClientIdsInt.Contains(x.ClientId ?? 0));
}
if (req.OptIdLists.Any())
{
predicate = predicate.And(x => req.OptIdLists.Contains(x.OptId ?? 0));
}
if (!string.IsNullOrEmpty(req.Number))
{
predicate = predicate.And(x => x.Number.Contains(req.Number));
}
if (req.HappenDateStart.HasValue)
{
predicate = predicate.And(x => x.HappenDate >= req.HappenDateStart);
}
if (req.HappenDateEnd.HasValue)
{
predicate = predicate.And(x => x.HappenDate < req.HappenDateEnd.Value.AddDays(1));
}
if (req.OptDateStart.HasValue)
{
predicate = predicate.And(x => x.OptDate >= req.OptDateStart);
}
if (req.OptDateEnd.HasValue)
{
predicate = predicate.And(x => x.OptDate < req.OptDateEnd.Value.AddDays(1));
}
var approvalQuery = DbContext.approvalprocess.Where(x => x.processType == "OutCashProcess");
var approvalCount = approvalQuery.Count();
var query = from cashout in DbContext.ClientCashInCashOut.Where(predicate)
join approval in approvalQuery on cashout.ApprovalProcess equals approval.order
select new EntryExitApprovalQueryRes
{
id = cashout.id,
EncryptId = cashout.EncryptId,
ProcessStatus = "审批中 流程" + (cashout.ApprovalProcess - 1) + "/" + approvalCount,
ProcessOrderId = cashout.ApprovalProcess,
Number = cashout.Number,
ProcessRoleId = approval.roleId,
Direction = cashout.Direction,
Money = cashout.Money ?? 0,
HappenDate = cashout.HappenDate,
Comments = cashout.Comments,
OptName = cashout.OptName,
OptDate = cashout.OptDate,
ClientName = cashout.ClientName,
CreatorId = cashout.CreatorId,
CreatorName = cashout.CreatorName,
CreateDate = cashout.CreateDate
};
if (string.IsNullOrEmpty(req.sidx))
{
req.sidx = "id";
req.sord = "desc";
}
query = query.OrderByDescending(s => s.OptDate);
var retListResult = query.ToSearchList(req);
var listRoles = new ErpBaseContext().Roles.Select(n => new { n.Id, n.Name }).ToDictionary(n => n.Id, m => m.Name);
foreach (var item in retListResult.rows)
{
item.id = 0;//不做接口返回
if (listRoles.TryGetValue(item.ProcessRoleId, out var name))
{
item.ProcessRoleName = name;
}
}
return retListResult;
}
}
/// <summary>
/// 出入金Api请求参数
/// </summary>
public class SaveEntryexitApiReq
{
/// <summary>
/// 客户Id
/// </summary>
public int? ClientId { get; set; }
/// <summary>
/// 客户名称
/// </summary>
public string ClientName { get; set; }
/// <summary>
/// 出入金方向
/// </summary>
public string Direction { get; set; }
/// <summary>
/// 金额
/// </summary>
public double? Money { get; set; }
/// <summary>
/// 银行账号
/// </summary>
public string OpenBankCard { get; set; }
/// <summary>
/// 发生时间
/// </summary>
public DateTime HappenDate { get; set; }
/// <summary>
/// 备注
/// </summary>
public string Comments { get; set; }
/// <summary>
/// 资金标识
/// </summary>
public ClientCashFlag CashFlag { get; set; }
}
/// <summary>
/// 财务汇总-API接口参数
/// </summary>
public class ClientBalanceGapReq
{
/// <summary>
/// 主键
/// </summary>
public int id { get; set; }
/// <summary>
/// 客户名称
/// </summary>
public string ClientName { get; set; }
/// <summary>
/// 结束日期
/// </summary>
public DateTime ValueDate { get; set; }
/// <summary>
/// 净资金流入
/// </summary>
public double? NetFund { get; set; }
/// <summary>
/// 期权费收支
/// </summary>
public double? OptionPremium { get; set; }
/// <summary>
/// 结算收支
/// </summary>
public double? SettlementBalance { get; set; }
/// <summary>
/// 票息
/// </summary>
public double? Coupon { get; set; }
/// <summary>
/// 互换收支
/// </summary>
public double? SwapBalance { get; set; }
/// <summary>
/// 其他收支
/// </summary>
public double? OtherFund { get; set; }
/// <summary>
/// 当日资金余额
/// </summary>
public double? ToDayRemainFund { get; set; }
/// <summary>
/// 授信额度
/// </summary>
public double? Credit { get; set; }
/// <summary>
/// 应付了交易结款
/// </summary>
public double? ClosedTradePayableFund { get; set; }
/// <summary>
/// 应付存续交易款
/// </summary>
public double? PositionTradePayableFund { get; set; }
/// <summary>
/// 追保金额
/// </summary>
public double? MarginByPayableMargin { get; set; }
/// <summary>
/// 应付资金总额
/// </summary>
public double? PayableFund { get; set; }
/// <summary>
/// 实现盈亏
/// </summary>
public double? WinLoss { get; set; }
/// <summary>
/// 持仓盈亏
/// </summary>
public double? PositionPnl { get; set; }
/// <summary>
/// 持仓市值
/// </summary>
public double? PositionPv { get; set; }
/// <summary>
/// 应付预付金
/// </summary>
public double? PayableMargin { get; set; }
/// <summary>
/// 是否为外部预付金
/// </summary>
public bool IsImportOuterMargin { get; set; }
}
}