using YLErp.BLL;
using YLErp.DBModels;
using YLErp.Modules.SwapModule;
namespace YLErp.Modules.SwapModule
{
///
/// BUG-01 方向守护(2026-08-24):授信出入表金额口径 占用记正/释放记负——
/// 已使用授信 = SUM(amount) 随占用上升、随释放回落;可用授信 = 有效授信 − 已使用授信 随占用收缩。
/// 连 dev 库闭环验证 Occupy/Release/GetUsedCredit(哨兵 client_id 自建自清,不触碰真实客户)。
///
[TestClass]
public class ClientCreditInoutSignTest
{
private const int SentinelClientId = 99064001; //哨兵客户号(不存在的客户,仅授信出入表按 client_id 记账)
private YLContext db;
private ClientCreditInoutService service;
[TestInitialize]
public void Init()
{
db = new YLContext();
Cleanup();
service = new ClientCreditInoutService(OptUserInfo.SystemUser);
}
[TestCleanup]
public void Teardown()
{
Cleanup();
db.Dispose();
}
private void Cleanup()
{
var olds = db.client_credit_inout.Where(x => x.client_id == SentinelClientId).ToList();
if (olds.Count > 0)
{
db.client_credit_inout.RemoveRange(olds);
db.SaveChanges();
}
}
/// 占用记正数:占用越多已使用授信越大(修复前为负——"越占越多"BUG-01)
[TestMethod]
public void CR_001_占用记正_已使用授信上升()
{
service.Occupy(SentinelClientId, 900001L, 800001, 10000, DateTime.Today, "方向守护-占用1");
Assert.AreEqual(10000, ClientCreditInoutService.GetUsedCredit(SentinelClientId, db), 1e-6);
service.Occupy(SentinelClientId, 900002L, 800002, 5000, DateTime.Today, "方向守护-占用2");
Assert.AreEqual(15000, ClientCreditInoutService.GetUsedCredit(SentinelClientId, db), 1e-6);
}
/// 释放记负数:已使用授信回落,快照 used_after 同口径
[TestMethod]
public void CR_002_释放记负_已使用授信回落()
{
service.Occupy(SentinelClientId, 900001L, 800001, 10000, DateTime.Today, "方向守护-占用");
service.Release(SentinelClientId, 900001L, 800001, 4000, DateTime.Today, "方向守护-释放");
var used = ClientCreditInoutService.GetUsedCredit(SentinelClientId, db);
Assert.AreEqual(6000, used, 1e-6);
//快照列与求和口径一致(最后一次写完后的已使用授信)
var last = db.client_credit_inout.Where(x => x.client_id == SentinelClientId).OrderByDescending(x => x.id).First();
Assert.AreEqual(6000, last.used_after, 1e-6);
Assert.AreEqual(-4000, last.amount, 1e-6, "释放行 amount 记负数");
}
/// 方向传导:可用授信 = 有效授信 − 已使用授信,占用使其收缩(BUG-01 修复后的业务语义)
[TestMethod]
public void CR_003_可用授信随占用收缩()
{
service.Occupy(SentinelClientId, null, 800003, 10000, DateTime.Today, "方向守护-占用");
var used = ClientCreditInoutService.GetUsedCredit(SentinelClientId, db);
var effective = 30000d; //有效授信给定量
Assert.AreEqual(20000, effective - used, 1e-6, "占用 10000 后可用授信应从 30000 收缩到 20000");
}
/// Occupy/Release 入口对传入符号容错(一律按数量取绝对值定方向),防调用方残留旧负号
[TestMethod]
public void CR_004_语义入口符号容错()
{
//即使调用方按旧习惯传负数,Occupy 也记正(数量口径),防止新代码库中残留旧符号调用点
var rec = service.Occupy(SentinelClientId, null, 800004, -7000, DateTime.Today, "方向守护-负号容错");
Assert.AreEqual(7000, rec.amount, 1e-6);
var rel = service.Release(SentinelClientId, null, 800004, -3000, DateTime.Today, "方向守护-负号容错");
Assert.AreEqual(-3000, rel.amount, 1e-6);
}
}
}