test(trade): 补 23108016 互换/期权本次名义本金分支单元测试

抽 CalcSwapCloseNotionalFromEventData 和 CalcOptionCloseNotional 为 public static 纯函数, BuildTriggerContext 了结场景改为调用这两个函数. 新增 13 个单元测试覆盖: 互换分支 EventData null/空/非法JSON/正数/负数/零 容错与绝对值, 期权分支 两者null/单边null/正数相乘/负数容错 绝对值语义. 重点锁定静默 catch 容错契约, 防止 EventData 异常时名义本金变 0 绕过审批阈值.
This commit is contained in:
hjhan
2026-07-17 08:45:49 +08:00
parent 2395aa9856
commit 21b86c871f
2 changed files with 165 additions and 17 deletions
@@ -1,4 +1,4 @@
using BaseOUDAL;
using BaseOUDAL;
using YLErp.BLL;
using YLErp.DBModels.Consts;
using YLErp.DBModels.Enums;
@@ -210,18 +210,7 @@ namespace YLErp.Modules.TradeModule
&& (x.EventType == (int)SwapEventTypeEnum. || x.EventType == (int)SwapEventTypeEnum.))
.OrderByDescending(x => x.id)
.FirstOrDefault();
if (swapEvent != null && !string.IsNullOrEmpty(swapEvent.EventData))
{
try
{
var unwindData = Newtonsoft.Json.JsonConvert.DeserializeObject<UnwindData>(swapEvent.EventData);
if (unwindData != null)
{
ctx.CurrentNotional = Math.Abs((double)unwindData.CloseNotionalValue);
}
}
catch { }
}
ctx.CurrentNotional = CalcSwapCloseNotionalFromEventData(swapEvent?.EventData);
}
else
{
@@ -230,15 +219,41 @@ namespace YLErp.Modules.TradeModule
.Where(t => t.TradeId == td.id && t.ValidState == ConsGlobal.InValid && !t.IsDeleted)
.OrderByDescending(t => t.id)
.FirstOrDefault();
if (tc != null && tc.UnwindPercentRate.HasValue && td.OriginalStockEqvNotional.HasValue)
{
ctx.CurrentNotional = Math.Abs(td.OriginalStockEqvNotional.Value * tc.UnwindPercentRate.Value);
}
ctx.CurrentNotional = CalcOptionCloseNotional(td.OriginalStockEqvNotional, tc?.UnwindPercentRate);
}
}
return ctx;
}
/// <summary>
/// 互换:从 swap_event.EventData(JSON) 反序列化取 CloseNotionalValue 绝对值。
/// 容错:EventData 为 null/空/非法 JSON / unwindData=null 时返回 0(不影响审批阈值判断)。
/// 抽为静态纯函数以支持无库单测。
/// </summary>
public static double CalcSwapCloseNotionalFromEventData(string eventData)
{
if (string.IsNullOrEmpty(eventData)) return 0;
try
{
var unwindData = Newtonsoft.Json.JsonConvert.DeserializeObject<UnwindData>(eventData);
return unwindData != null ? Math.Abs((double)unwindData.CloseNotionalValue) : 0;
}
catch
{
return 0;
}
}
/// <summary>
/// 期权:当次平仓名义本金 = 期初名义本金 × 平仓比例(UnwindPercentRate),取绝对值。
/// 容错:任一参数为 null 时返回 0。抽为静态纯函数以支持无库单测。
/// </summary>
public static double CalcOptionCloseNotional(double? originalStockEqvNotional, double? unwindPercentRate)
{
if (!originalStockEqvNotional.HasValue || !unwindPercentRate.HasValue) return 0;
return Math.Abs(originalStockEqvNotional.Value * unwindPercentRate.Value);
}
/// <summary>
/// 需求①:判断按触发条件是否需要审批。
/// <para>取该交易类别的审批流程,若所有节点配置的触发条件都不满足当前业务,则无需审批(返回 false)。</para>