Files
zszq-trs/YLErpDAL/Modules/SuperviseReportModule/CFMMC2022/Service/SuperviseReportClientCashService.cs
T
2024-05-09 14:06:26 +08:00

497 lines
27 KiB
C#

using BaseOUDAL;
using Dapper;
using System.ComponentModel.DataAnnotations.Schema;
using System.Text;
using YLErp.BLL;
using YLErp.Helpers;
using YLErp.Model;
using YLErp.Model.Enum;
using YLErp.Modules.SuperviseReportModule.CFMMC2022.Model;
namespace YLErp.Modules.SuperviseReportModule.CFMMC2022.Service
{
/// <summary>
/// 监管报告-客户资金服务
/// </summary>
public class SuperviseReportClientCashService : YLBaseService
{
public SuperviseReportClientCashService(OptUserInfo userInfo) : base(userInfo)
{
}
/// <summary>
/// 计算出客户资金信息
/// </summary>
public SearchListResult<NewSuperviseReportClientCashModel> NewSearchSuperviseReportList(SuperviseReportReq req, IEnumerable<int> clienIds = null)
{
if (string.IsNullOrWhiteSpace(req.sidx)) { req.sidx = "ClientId"; }
var config = DbContext.valuedate.FirstOrDefault(x => x.State == valuedate.当前使用);
var insidedClientIds = DataCacheProvider.GetClientDataSource().AsQueryable().Where(O => O.IsInsided == 1).Select(O => O.id).ToList();
#region 新增客户筛选 tw
if (clienIds != null)
{
insidedClientIds = insidedClientIds.Where(l => clienIds.Contains(l)).ToList();
}
#endregion
SuperviseReportClientCashModelEx[] tempQuery = null;
List<int> clientIds = new List<int>();
if (req.DataType != null && !req.DataType.Contains("全量客户"))
{
foreach (var dataType in req.DataType)
{
switch (dataType)
{
case "有持仓":
clientIds.AddRange(DbContext.eod_trade.Where(O => O.ValueDate == req.ValueDate).Select(O => O.ClientId));
break;
case "有资金":
clientIds.AddRange(from cb in DbContext.ClientBalanceDaily.Where(n => n.BalanceDate == req.ValueDate)
join cr in DbContext.credit.Where(n => n.ProcessStatus == "已审批" && (n.CreditStartDate == null || n.CreditStartDate <= req.ValueDate) && n.CreditDeadLine >= req.ValueDate)
on cb.ClientId equals cr.ClientId into t_cr
from cr in t_cr.DefaultIfEmpty()
where !((cb.ToDayRemainFund == null || (cb.ToDayRemainFund < 0.0001 && cb.ToDayRemainFund > -0.0001)) &&
(cb.MarginBalance == null || (cb.MarginBalance < 0.0001 && cb.MarginBalance > -0.0001)) &&
(cb.PayableMargin == null || (cb.PayableMargin < 0.0001 && cb.PayableMargin > -0.0001)) &&
(cb.PositionPremiumNetCash == null || (cb.PositionPremiumNetCash < 0.0001 && cb.PositionPremiumNetCash > -0.0001)) &&
(cr == null || cr.Credit == null || (cr.Credit < 0.0001 && cr.Credit > -0.0001)))
select cb.ClientId);
break;
}
}
if (clientIds.Any())
{
clientIds = clientIds.Distinct().ToList();
var parentClientIds = new HashSet<int>(clientIds);
foreach (var item in clientIds)
{
Client clientInfo = DataCacheProvider.GetClientDataSource().GetData(item);
do
{
if (clientInfo == null)//客户不存在,提示错误
{
throw new ServiceException($"{clientInfo.Name} 的所属机构不存在,请维护后生成!");
}
if (clientInfo.IsInsided == 1)//跳过内部客户
{
break;
}
if (clientInfo.ParentId == 0)//没有父客户则跳出;
{
break;
}
clientInfo = DataCacheProvider.GetClientDataSource().GetData(clientInfo.ParentId);
if (clientInfo != null)//将找到的父客户Id增加到客户列表
{
parentClientIds.Add(clientInfo.ParentId);
}
} while (true);
}
clientIds = parentClientIds.ToList();
}
}
else
{
if (PS.Config.Is浙期)
{
using (var clientDb = DbContextFactory.GetClientDbContext(OptUser))
{
var tempIds = (from cb in clientDb.client_black
join c in clientDb.client
on cb.Name equals c.Name
select c.id).ToList();
if (tempIds.Count > 0)
{
insidedClientIds.AddRange(tempIds);
}
}
}
}
if (clienIds != null)
{
clientIds.AddRange(clienIds);
}
tempQuery = QueryList(req, insidedClientIds, clientIds, out var count);
var result = new SearchListResult<SuperviseReportClientCashModelEx>
{
records = count,
rows = tempQuery,
page = req.page
};
result.total = (result.records - 1) / req.rows + 1;
var clientIdArr = result.rows.Select(O => O.ClientId).ToHashSet();
//一级子客户
var subClientIdArr = DataCacheProvider.GetClientDataSource().AsQueryable(O => clientIdArr.Contains(O.ParentId) && O.IsDocShowParentName == 1).Select(O => O.id);
//二级子客户
subClientIdArr.Concat(DataCacheProvider.GetClientDataSource().AsQueryable(O => subClientIdArr.Contains(O.ParentId) && O.IsDocShowParentName == 1).Select(O => O.id));
Dictionary<int, List<SuperviseReportClientCashModelEx>> cbDict = null;
if (subClientIdArr.Any())
{
cbDict = QueryList(req, null, subClientIdArr.ToList(), out _, 1).GroupBy(O => O.ParentId).ToDictionary(K => K.Key, V => V.ToList());
clientIdArr = clientIdArr.Concat(subClientIdArr).ToHashSet();
}
else
{
cbDict = new Dictionary<int, List<SuperviseReportClientCashModelEx>>();
}
var creditDict = DbContext.CreditFromClient.Where(O => clientIdArr.Contains(O.ClientId) && O.CreditStartDate <= req.ValueDate && O.CreditDeadLine >= req.ValueDate).ToDictionary(K => K.ClientId);
var productDict =
DbContext.clientcashincashout_product
.Where(O =>
(O.Status == Clientcashincashout_productStatusEnum.抵押.ToString() && O.OptStatus == ClientCashInCashOut.已确认
|| O.Status == Clientcashincashout_productStatusEnum.赎回.ToString() && O.OptStatus != ClientCashInCashOut.已确认
|| O.Status == Clientcashincashout_productStatusEnum.赎回.ToString() && O.OptStatus == ClientCashInCashOut.已确认
&& O.BackDate >= req.ValueDate) && clientIdArr.Contains(O.ClientId) && O.HappenDate < req.ValueDate && O.Comments != null && O.Comments != "")
.AsEnumerable().GroupBy(O => O.ClientId).ToDictionary(K => K.Key, V => V.FirstOrDefault().Comments);
var clientMetaQuery = DbContextFactory.GetClientDbContext(UserInfo).ClientMeta.Where(O => clientIdArr.Contains(O.ClientId));
var clientReportInfo = clientMetaQuery.Where(O => O.MetaKey == "ReportName").ToDictionary(K => K.ClientId, V => V.MetaValue);
var marginPayTimeInfo = clientMetaQuery.Where(O => O.MetaKey == "追保到账时间").ToDictionary(K => K.ClientId, V => V.MetaValue);
var clientcontext = new ClientDBContext();
string marginPayTime = "";
var sDate = req.ValueDate;
var eDate = sDate.AddDays(1);
var cashOther = DbContext.client_cash_other.Where(O => clientIdArr.Contains(O.ClientId ?? 0) && O.HappenDate >= sDate && O.HappenDate < eDate).ToList();
//暂时增加时间保证不报错
DbContext.Database.SetCommandTimeout(600);
//子公司抵押品
var companycollaterInfo = (from source in DbContext.company_collateral
join underlying in DbContext.underlying_manager on source.UnderlyingId equals underlying.id into underlying_manager
from underlying in underlying_manager.DefaultIfEmpty()
join commodityFuturePrice in DbContext.eod_commodity_future_price.Where(n => n.ValueDate == req.ValueDate) on underlying.UnderlyingCode equals commodityFuturePrice.UnderlyingCode
into commodityFuturePrices
from commodityFuturePrice in commodityFuturePrices.DefaultIfEmpty()
join stockPrice in DbContext.eod_stock_price.Where(n => n.ValueDate == req.ValueDate) on underlying.UnderlyingCode equals stockPrice.UnderlyingCode
into stockPrices
from stockPrice in stockPrices.DefaultIfEmpty()
join v in DbContext.variety on source.VarietyId equals v.id into variety
from v in variety.DefaultIfEmpty()
where req.ValueDate >= source.HappenDate && clientIdArr.Contains(source.ClientId) && source.OptStatus == "已确认" && source.Status == company_collateralStatusEnum.抵押.ToString()
select new company_collateralLinq
{
ClientId = source.ClientId,
Comments = source.Comments ?? "",
ProductTotalPrice = source.ProductAmount * source.Rate * (commodityFuturePrice != null ? (valuedateBLL.SystemDate.EodSettlePriceMode == "结算价" ? commodityFuturePrice.SettlePrice : commodityFuturePrice.ClosePrice) : (stockPrice != null ? stockPrice.ClosePrice : (underlying == null ? 0 : underlying.Price))),
}).ToList();
using (ErpBaseContext basedb = new ErpBaseContext())
{
marginPayTime = (from di in basedb.DictionaryItems
join d in basedb.Dictionaries
on di.DictId equals d.Id
where d.Name == "资金报送追保到账时间"
select di.ShortName).FirstOrDefault();
}
int startIndex = req.rows * result.page - req.rows, i = 1;
var tradeList =
(from t in DbContext.eod_trade
where t.ValueDate == req.ValueDate && t.TradeStatus == "确认成交"
select new xodTradeBase() { TradeJson = t.TradeJson })
.ToArray().Select(O => O.trade);
foreach (var item in result.rows)
{
var marginPayTimeValue = marginPayTimeInfo.TryGetValue(item.ClientId, out var temp) ? temp : marginPayTime;
i = SetReportObj(req, config, creditDict, productDict, clientReportInfo, marginPayTimeValue, cashOther, companycollaterInfo, startIndex, i, item);
//item.ToClientCredit = item.ToClientCredit.OtcFormatValue(2);
//item.ClientTradePriceCredit = item.ClientTradePriceCredit.OtcFormatValue(2);
//item.ClientPositionCredit = item.ClientPositionCredit.OtcFormatValue(2);
//item.PositionTradePriceOut = item.PositionTradePriceOut.OtcFormatValue(2);
//item.ToCompanyCredit = item.ToCompanyCredit?.OtcFormatValue(2);
//item.CompanyTradePriceCredit = item.CompanyTradePriceCredit.OtcFormatValue(2);
//item.CompanyPositionCredit = item.CompanyPositionCredit.OtcFormatValue(2);
//item.PositionTradePriceIn = item.PositionTradePriceIn.OtcFormatValue(2);
if (cbDict.TryGetValue(item.ClientId, out var list))
{
foreach (var obj in list)
{
marginPayTimeValue = marginPayTimeInfo.TryGetValue(item.ClientId, out temp) ? temp : marginPayTime;
SetReportObj(req, config, creditDict, productDict, clientReportInfo, marginPayTimeValue, cashOther, companycollaterInfo, startIndex, 0, obj);
item.OpenBalance += obj.OpenBalance.OtcFormatValue(2);
item.TodayCashInCashOut += obj.TodayCashInCashOut.OtcFormatValue(2);
item.TodaySettleEarnings += obj.TodaySettleEarnings.OtcFormatValue(2);
item.TodayOpenTradePrice += obj.TodayOpenTradePrice.OtcFormatValue(2);
item.EndBalance += obj.EndBalance.OtcFormatValue(2);
item.ClientMarginHold += obj.ClientMarginHold?.OtcFormatValue(2);
item.CompanyMarginHold += obj.CompanyMarginHold?.OtcFormatValue(2);
item.AvailableCash += obj.AvailableCash.OtcFormatValue(2);
item.DesirableFund += obj.DesirableFund.OtcFormatValue(2);
item.AddFunds += obj.AddFunds.OtcFormatValue(2);
item.PositionValue += obj.PositionValue.OtcFormatValue(2);
item.MarketValueEquity += obj.MarketValueEquity.OtcFormatValue(2);
item.PositionPnl += obj.PositionPnl?.OtcFormatValue(2);
item.PositionPremiumNetCash += obj.PositionPremiumNetCash.OtcFormatValue(2);
item.ToDayRemainFund += obj.ToDayRemainFund.OtcFormatValue(2);
item.TodayRemianFundProduct += obj.TodayRemianFundProduct.OtcFormatValue(2);
}
}
}
return new SearchListResult<NewSuperviseReportClientCashModel>(result, result.rows);
}
private int SetReportObj(SuperviseReportReq req, valuedate config, Dictionary<int, CreditFromClient> creditDict, Dictionary<int, string> productDict, Dictionary<int, string> clientReportInfo, string marginPayTime, List<client_cash_other> cashOther, List<company_collateralLinq> companycollaterInfo, int startIndex, int i, SuperviseReportClientCashModelEx item)
{
item.CompanyName = config.SuperviseMainName;
item.CompanyLicenseCode = config.SuperviseMainCode;
item.Date = req.ValueDate;
if (creditDict.TryGetValue(item.ClientId, out var credit))
{
item.ToCompanyCredit = credit.Credit;
item.Remark = credit.Comments ?? "";
}
var marginHold = item.ClientMarginHold;
var client = DataCacheProvider.GetClientDataSource().GetData(item.ClientId);
if (client != null)
{
item.CustomerNature2 = client.CustomerNature2 ?? "";
item.ClientName = clientReportInfo.TryGetValue(client.id, out var reportName) && !string.IsNullOrWhiteSpace(reportName) ? reportName : client.Name;
item.ClientType = client.CustomerNature2;
item.ClientLicenseCode = client.LicenseCode;
//获取交易对手方LEI
item.ClientLEI = client.LEICode;
}
else
{
return i;
}
//当日出入金需要从client_cash_other表中获取当天记录
if (PS.Config.ErpElement.IsSumOthersOnClientCash)
{
item.TodayCashInCashOut += cashOther.Where(O => O.ClientId.Value == client.id).Sum(O => O.Money ?? 0);
}
item.MarginType = ((MarginOptionEnum)client.MarginOptionType).ToString();
item.MarginPayTime = marginPayTime;
item.id = item.Index = startIndex + i++;
item.PositionTradePriceOut = 0;
item.PositionTradePriceIn = 0;
switch (item.MarginType)
{
case "单向追保":
item.MarginCollectionMode = "子公司向对手方单向收预付金";
item.CompanyMarginHold = 0;
item.ClientMarginHold = Math.Abs(marginHold ?? 0);
break;
case "对手方单向追保":
item.MarginCollectionMode = "对手方向子公司单向收预付金";
item.CompanyMarginHold = Math.Abs(marginHold ?? 0);
item.ClientMarginHold = 0;
break;
case "双向追保":
item.MarginCollectionMode = "子公司和对手方互收预付金";
item.ClientMarginHold = Math.Max(0, (marginHold ?? 0));
if (PS.Config.Company != Configuration.CompanyEnum.弘业)
{
item.CompanyMarginHold = Math.Abs(Math.Min(0, (marginHold ?? 0)));//这里赋值是必要的,否则计算时会当做0去计算;
}
item.CompanyMarginHold = null;
if (PS.Config.Company == Configuration.CompanyEnum.国投)
{
item.CompanyMarginHold = 0;
}
break;
case "其他":
default:
item.MarginCollectionMode = "双方互不收取预付金";
break;
}
if (item.ClientType == "风险管理子公司")
{
item.ToCompanyCredit = null;
}
item.AddFunds = Math.Max(-item.AvailableCash, 0);
item.ToClientCredit = item.ToClientCredit.OtcFormatValue(2);
item.ClientTradePriceCredit = item.ClientTradePriceCredit.OtcFormatValue(2);
item.ClientPositionCredit = item.ClientPositionCredit.OtcFormatValue(2);
item.PositionTradePriceOut = item.PositionTradePriceOut.OtcFormatValue(2);
item.ToCompanyCredit = item.ToCompanyCredit?.OtcFormatValue(2);
item.CompanyTradePriceCredit = item.CompanyTradePriceCredit.OtcFormatValue(2);
item.CompanyPositionCredit = item.CompanyPositionCredit.OtcFormatValue(2);
item.PositionTradePriceIn = item.PositionTradePriceIn.OtcFormatValue(2);
item.OpenBalance = item.OpenBalance.OtcFormatValue(2);
item.TodayCashInCashOut = item.TodayCashInCashOut.OtcFormatValue(2);
item.TodaySettleEarnings = item.TodaySettleEarnings.OtcFormatValue(2);
item.TodayOpenTradePrice = item.TodayOpenTradePrice.OtcFormatValue(2);
item.EndBalance = item.EndBalance.OtcFormatValue(2);
item.ClientMarginHold = item.ClientMarginHold?.OtcFormatValue(2);
item.CompanyMarginHold = item.CompanyMarginHold?.OtcFormatValue(2);
item.AvailableCash = item.AvailableCash.OtcFormatValue(2);
item.DesirableFund = item.DesirableFund.OtcFormatValue(2);
item.AddFunds = item.AddFunds.OtcFormatValue(2);
item.PositionValue = item.PositionValue.OtcFormatValue(2);
item.MarketValueEquity = item.MarketValueEquity.OtcFormatValue(2);
item.PositionPnl = item.PositionPnl?.OtcFormatValue(2);
item.PositionPremiumNetCash = item.PositionPremiumNetCash.OtcFormatValue(2);
item.ToDayRemainFund = item.ToDayRemainFund.OtcFormatValue(2);
item.TodayRemianFundProduct = item.TodayRemianFundProduct.OtcFormatValue(2);
item.ClientNumber = client.Number;
if (client.ParentId != 0)
{
var parentClient = DataCacheProvider.GetClientDataSource().GetData(client.ParentId);
item.ParentClientNumber = parentClient?.Number;
}
item.NonCashPerformanceGuaranteesType = formatGuaranteesType((productDict.TryGetValue(client.id, out var remark) ? remark : ""));
item.NonCashPerformanceGuaranteesValuation = item.TodayRemianFundProduct.OtcFormatMoney();
if (companycollaterInfo.Count > 0)
{
var ccInfo = companycollaterInfo.Where(O => O.ClientId == item.ClientId).FirstOrDefault();
item.ChildNonCashPerformanceGuaranteesType = formatGuaranteesType(ccInfo != null ? ccInfo.Comments : "");
}
else
{
item.ChildNonCashPerformanceGuaranteesType = "无";
}
var collaterVal = companycollaterInfo.Where(O => O.ClientId == item.ClientId).Sum(O => O.ProductTotalPrice);
item.ChildNonCashPerformanceGuaranteesValuation = collaterVal.OtcFormatMoney();
return i;
}
/// <summary>
///
/// </summary>
/// <param name="req"></param>
/// <param name="insidedClientIds">要排除的客户Id</param>
/// <param name="clientIds">要包含的客户Id</param>
/// <param name="count"></param>
/// <param name="queryMode">
/// <para>查询模式:</para>
/// <para>0:主查询,仅查询出需要报送的交易;</para>
/// <para>1:附加查询,根据客户Id查询出所有匹配的记录,不排序,不分页;</para>
/// <para>默认:0</para>
/// </param>
/// <returns></returns>
private SuperviseReportClientCashModelEx[] QueryList(SuperviseReportReq req, List<int> insidedClientIds, List<int> clientIds, out int count, int queryMode = 0)
{
#region Sql
var sqlSelect = new StringBuilder();
sqlSelect.Append("cb.ClientId as 'ClientId' ");
sqlSelect.Append(",c.ParentId as 'ParentId' ");
sqlSelect.Append(",'' as 'CustomerNature2' ");
sqlSelect.Append(",IFNULL(cb.PositionPremiumNetCash,0) as 'PositionPremiumNetCash' ");
sqlSelect.Append(",IFNULL(cb.ToDayRemainFund,0) as 'ToDayRemainFund' ");
sqlSelect.Append(",cb.ToDayRemainFund as 'CompanyName' ");
sqlSelect.Append(",IFNULL(cb.Credit,0) as 'ToClientCredit' ");
sqlSelect.Append(",IFNULL(cb.TodayRemianFundProduct,0) as 'TodayRemianFundProduct' ");
sqlSelect.Append(",IFNULL(cb.LastDayRemainFund,0) as 'OpenBalance' ");
sqlSelect.Append(",IFNULL(cb.NetFund,0) as 'TodayCashInCashOut' ");
sqlSelect.Append(",IFNULL(cb.SettlementBalance, 0) + IFNULL(cb.Coupon, 0) + IFNULL(cb.SwapBalance, 0) as 'TodaySettleEarnings' ");
sqlSelect.Append(",IFNULL(cb.OptionPremium, 0) + IFNULL(cb.OptionPremiumSwap, 0) as 'TodayOpenTradePrice' ");
sqlSelect.Append(",-cb.PayableMargin as 'ClientMarginHold' ");
sqlSelect.Append(",IF(cb.Margin>0,IFNULL(cb.Margin, 0), 0) as 'AddFunds' ");
sqlSelect.Append($",IFNULL(IF({PS.Config.IsPVRounded},cb.RoundedPv, cb.Pv), 0) as 'PositionValue' ");
sqlSelect.Append(",cb.PositionPnl as 'PositionPnl' ");
var sqlStr = new StringBuilder();
sqlStr.Append("SELECT ");
sqlStr.Append("{0} ");
sqlStr.Append($"FROM `{DbContextFactory.GetClientDbContext(UserInfo).Database.GetDbConnection().Database}`.client c ");
sqlStr.Append($"JOIN `{DbContext.Database.GetDbConnection().Database}`.clientbalancedaily cb on c.id = cb.ClientId ");
sqlStr.Append($"WHERE cb.BalanceDate = '{req.ValueDate.ToString("yyyy-MM-dd")}' ");
if (insidedClientIds?.Any() ?? false)
{
sqlStr.Append($"AND NOT c.id IN ({string.Join(",", insidedClientIds)}) ");
}
if (queryMode != 1)
{
//只查询需要单独报送的客户;
sqlStr.Append($"AND (c.IsDocShowParentName is null Or c.IsDocShowParentName <> 1 Or (c.IsDocShowParentName = 1 And c.ParentId <= 0)) ");
}
if (clientIds.Count > 0)
{
sqlStr.Append($"AND c.id IN ({string.Join(",", clientIds)}) ");
}
sqlStr.Append("{1} ;");
var sqlLimit = queryMode == 1 ? "" : $"Order By {req.sidx ?? "id"} {req.sord} LIMIT {req.rows * (req.page - 1)},{req.rows}";
#endregion
count =
DbContext.Database.GetDbConnection().Query<int>(
string.Format(sqlStr.ToString(), "Count(c.id)", ""),
commandTimeout: 600
//,
//new SqlParameter("@clientDb", DbContextFactory.GetClientDbContext(UserInfo).Database.Connection.Database),
//new SqlParameter("@dmsDb", DbContext.Database.Connection.Database)
).ToArray().FirstOrDefault();
LogFactory.GetLogger("客户资金报表2022").Info($"QueryList sql:{sqlStr.ToString()},{sqlSelect.ToString()},{sqlLimit}");
return DbContext.Database.GetDbConnection().Query<SuperviseReportClientCashModelEx>(
string.Format(sqlStr.ToString(), sqlSelect.ToString(), sqlLimit),
commandTimeout: 600
//,
//new SqlParameter("@clientDb", DbContextFactory.GetClientDbContext(UserInfo).Database.Connection.Database),
//new SqlParameter("@dmsDb", DbContext.Database.Connection.Database),
//new SqlParameter("@sidx", req.sidx ?? "id"),
//new SqlParameter("@sord", req.sord)
).ToArray();
}
[NotMapped]
class SuperviseReportClientCashModelEx : NewSuperviseReportClientCashModel
{
public double TodayRemianFundProduct { get; set; }
}
private string formatGuaranteesType(string creditRemark)
{
var guaranteesType = "";
if (creditRemark.Contains("商品标准仓单"))
{
guaranteesType = "商品标准仓单";
}
else if (creditRemark.Contains("商品非标仓单"))
{
guaranteesType = "商品非标仓单";
}
else if (creditRemark.Contains("商品现货实物"))
{
guaranteesType = "商品现货实物";
}
else if (creditRemark.Contains("有价证券"))
{
guaranteesType = "有价证券";
}
else
{
if (creditRemark.Length > 0)
{
guaranteesType = "其他";
}
else
{
guaranteesType = "无";
}
}
return guaranteesType;
}
}
}