using YLErp.DBModels;
namespace YLErp.Modules.SwapModule.Accrual;
///
/// 融资腿逐日计息的跨日状态(不可变值对象)。
/// 这是"待实现利息"在日间滚动的快照,区别于已落库的 swap_flow_event。
///
/// 旧字段 → 领域命名映射(DB 列不可改,仅在边界处适配;本类内部一律用下列自描述名):
///
/// - TdInterestPrincipal逐日滚动的计息本金 →
/// - InterestIncomeSum累计待实现利息 →
/// - consumedInterest历史已实现利息(legacy) →
/// - ValueDate快照截至日 → (EOD 续接起算日,Bug C / 5-11 跳过需据此判断从哪天接续)。
///
///
public readonly struct AccrualState
{
/// 用于计算当日利息的计息本金。单利=名义本金基数;复利=本金+累计利息。
public decimal AccrualPrincipal { get; }
/// 累计待实现(未平仓)利息。
public decimal UnrealizedInterest { get; }
/// 历史各次平仓已确认的已实现利息,从剩余待实现中扣除。
public decimal RealizedInterest { get; }
/// 快照截至日(来自 eod_swap_position.ValueDate)。编排层据此判断计息区间起点,避免 5-11 等"跳过日"误重算。
public DateTime ValueDate { get; }
public AccrualState(decimal accrualPrincipal, decimal unrealizedInterest, decimal realizedInterest, DateTime valueDate)
=> (AccrualPrincipal, UnrealizedInterest, RealizedInterest, ValueDate) = (accrualPrincipal, unrealizedInterest, realizedInterest, valueDate);
/// 向后兼容:未携带快照日期时(如纯内存构造)用默认日。
public AccrualState(decimal accrualPrincipal, decimal unrealizedInterest, decimal realizedInterest)
: this(accrualPrincipal, unrealizedInterest, realizedInterest, default) { }
/// 空状态(新开仓首个计息日之前)。
public static readonly AccrualState Zero = new(0m, 0m, 0m);
///
/// 从上一日日终归档 适配(边界适配:DB 列名 → 领域名)。
/// 仅映射计息状态;名义本金基数 / 平仓比例 / 已实现利息等由调用方另行传入。
///
public static AccrualState FromPreviousEod(eod_swap_position previousEod)
=> previousEod == null || previousEod.id == 0
? Zero
: new AccrualState(previousEod.TdInterestPrincipal, previousEod.InterestIncomeSum, 0m, previousEod.ValueDate);
}