BugFix 资金状况的初始保证金和授信额度 修改

This commit is contained in:
锦麟 王
2026-08-27 18:50:30 +08:00
parent 35d68acc02
commit 880489e2dc
4 changed files with 46 additions and 6 deletions
@@ -1,4 +1,4 @@
using Qdp.Foundation.Utilities;
using Qdp.Foundation.Utilities;
using System.ComponentModel.DataAnnotations.Schema;
using YLErp.DBModels;
@@ -253,6 +253,12 @@ namespace YLErp.Models
/// </summary>
public double TotalCredit { get; set; }
/// <summary>
/// 原始授信额度(展示用:credit 表 Σ(OriginalCredit ?? Credit),未经 MaxCreditUseRatio 折算;
/// TotalCredit 仍是折算后值,供可用资金/追保公式使用)
/// </summary>
public double OriginalTotalCredit { get; set; }
/// <summary>
/// 用户可用的名义本金规模
/// </summary>
@@ -303,6 +303,16 @@ namespace YLErp.BLL.EodSettlement
var usedCreditDic = ClientCreditInoutService.GetUsedCreditByClients(clientIdS, db);
var swapInitMarginDic = SwapSpanBalanceQueryService.GetSwapInitMarginByClients(clientIdS, lastDate, db);
var swapAdditionalDic = SwapSpanBalanceQueryService.GetTradeAdditionalMarginByClients(clientIdS, lastDate, db);
//原始授信额度(展示用):与 EOD 写入 clientbalancedaily.Credit 同批过滤条件(EodClientBalanceCalc :68),
//取 Σ(OriginalCredit ?? Credit) 不经比例折算;TotalCredit 仍为折算后值供公式使用
var originalCreditDic = db.credit.AsNoTracking()
.Where(t => t.ClientId != null && clientIdS.Contains(t.ClientId.Value)
&& t.ProcessStatus == "已审批"
&& (!t.CreditDeadLine.HasValue || t.CreditDeadLine >= lastDate)
&& (!t.CreditStartDate.HasValue || t.CreditStartDate <= lastDate))
.GroupBy(t => t.ClientId.Value)
.Select(g => new { ClientId = g.Key, Sum = g.Sum(t => (t.OriginalCredit ?? t.Credit) ?? 0d) })
.ToDictionary(x => x.ClientId, x => x.Sum);
foreach (var data in endDatas)
{
@@ -319,6 +329,7 @@ namespace YLErp.BLL.EodSettlement
balance.TotalCredit = data.TotalCredit;
balance.OriginalTotalCredit = originalCreditDic.TryGetValue(data.ClientId, out var originalCredit) ? originalCredit : 0;
balance.PayableMargin = data.PayableMargin;
balance.GuaranteesTotalAmount = data.GuaranteesTotalAmount;
balance.FrozenMarginMoney = data.FrozenMarginMoney;
@@ -671,6 +682,7 @@ namespace YLErp.BLL.EodSettlement
DicTotal.AvailableAmount += dc.Value.AvailableAmount;
DicTotal.TotalMarginTotal += dc.Value.TotalMargin;
DicTotal.TotalCredit += dc.Value.TotalCredit;
DicTotal.OriginalTotalCredit += dc.Value.OriginalTotalCredit;
DicTotal.WinLoss += dc.Value.WinLoss;
DicTotal.TdWinLoss += dc.Value.TdWinLoss;
DicTotal.PositionPremiumNetCash += dc.Value.PositionPremiumNetCash;
@@ -8,7 +8,8 @@ namespace YLErp.Modules.SwapModule.Margin
/// <summary>
/// R2 阶段三 §3.2 估值报告/可用资金查询输入(静态查询,供 ClientBalanceUtility 与 RealTimeClientBanlanceService 共用,保证三处口径一致)。
/// 口径:
/// - 互换初始保证金(净收取为正)= 客户 应付预付金 流水收付净额取反(客户应付入金记负、平仓返还为正,取负号后净收取为正);
/// - 互换初始保证金(净收取为正)= 客户 应付预付金 流水收付净额取反 + 初始预付金授信占用净额
/// (授信垫付的初始预付金无资金流水,2026-08-27 补入口径,否则授信垫付客户初始保证金展示为 0);
/// - 交易维度追加保证金(合约维度)= Σ(维持保证金 − 累计保证金):
/// 维持保证金取当日 trade_span.Spv(区间追保结构引擎产出,我方净收取为正);
/// 累计保证金 = 该交易 应付预付金+追加保证金 流水收付净额 + 追加保证金授信占用净额(§0 口径,阶段四 §4.1 起)
@@ -19,6 +20,8 @@ namespace YLErp.Modules.SwapModule.Margin
{
/// <summary>
/// 客户维度输入:互换初始保证金(净收取为正,按客户汇总)。
/// 初始保证金 = 应付预付金流水收付净额 + 初始预付金授信占用净额(非"追加保证金"前缀、关联交易)——
/// 授信垫付的初始预付金不产生资金流水,只算流水会把授信垫付部分漏掉(展示为 0)。
/// </summary>
public static Dictionary<int, double> GetSwapInitMarginByClients(List<int> clientIds, DateTime valueDate, YLContext db)
{
@@ -37,8 +40,26 @@ namespace YLErp.Modules.SwapModule.Margin
.Select(x => new { ClientId = x.ClientId ?? 0, Money = x.Money ?? 0d })
.ToList();
return flows.GroupBy(x => x.ClientId)
var result = flows.GroupBy(x => x.ClientId)
.ToDictionary(g => g.Key, g => -g.Sum(x => x.Money));
//初始预付金的授信占用净额(占用记正/释放记负,Σ(amount) 即净已缴;trade_id != null 排除人工调整类记录,
//"追加保证金"前缀为 EOD 追保占用,不计入初始保证金)
var initCredit = db.client_credit_inout.AsNoTracking()
.Where(x => clientIds.Contains(x.client_id)
&& x.trade_id != null
&& x.happen_date <= valueDate
&& (x.remark == null || !x.remark.StartsWith(ClientCreditInoutService.AdditionalMarginRemark)))
.GroupBy(x => x.client_id)
.Select(g => new { ClientId = g.Key, Sum = g.Sum(x => x.amount) })
.ToList();
foreach (var item in initCredit)
{
result[item.ClientId] = (result.TryGetValue(item.ClientId, out var cash) ? cash : 0d) + item.Sum;
}
return result;
}
/// <summary>
@@ -1,4 +1,4 @@
var g_grid = {};
var g_grid = {};
$(function () {
var PostData = {};
var calcDate = page.ValueDate;
@@ -291,7 +291,8 @@ function SearchClientBalance() {
main.post("/trade_span/GetClientLatestBalance", { clientId: $("#ClientId").val(), ValueDateFrom: param.ValueDateStart, ValueDateTo: param.ValueDateEnd, IsClientBalanceGap: param.IsClientBalanceGap, IsGetOuterMarginGap: param.IsGetOuterMarginGap, ParentFlag: param.ParentFlag }).done(function (data) {
$("#LastDayRemainFund").text(numFormart(data.LastDayRemainFund));
//R2 阶段三 §3.2 口径(BUG-07 修正,与邮件/Excel 报告 SettlementReportService 同源):
//初始保证金=SwapInitMargin(应付预付金净额)、维持保证金=MySideMarginclient_span 维持保证金反号聚合)
//初始保证金=SwapInitMargin(应付预付金净额+初始预付金授信占用净额)、维持保证金=MySideMarginclient_span 维持保证金反号聚合)
//授信额度=OriginalTotalCredit(原始授信值,未经最大可用比例折算;公式计算仍用折算后 TotalCredit
$("#SwapInitMargin").text(numFormart(data.SwapInitMargin));
$("#WinLoss").text(numFormart(data.WinLoss));
$("#CashInCashOutChange").text(numFormart(data.NetFundAll));
@@ -305,7 +306,7 @@ function SearchClientBalance() {
$("#MarginByPayableMargin").text(numFormart(data.MarginByPayableMarginTotal));
$("#ToDayRemainFund").text(numFormart(data.AmountFund));
$("#DesirableFund").text(numFormart(data.DesirableFundTotal));
$("#TotalCredit").text(numFormart(data.TotalCredit));
$("#TotalCredit").text(numFormart(data.OriginalTotalCredit));
$("#UsedCredit").text(numFormart(data.UsedCredit));
});