fix(trade): 标的除权0覆盖旧值
- 重命名 MergeNonZeroDividendValues 方法为 MergeDividendValues - 修改合并逻辑,数值字段(包括 0)都作为有效覆盖值进行合并 - 更新注释说明合并规则的变化 - 添加零现金分红覆盖现有值的单元测试 - 修复数据库记录合并时的字段覆盖逻辑
This commit is contained in:
@@ -133,6 +133,17 @@ namespace YLErp.Modules.SwapModule
|
||||
Assert.AreEqual(1m, GetSplit(target));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void ZeroCashDividendOverridesExistingValueDuringMerge()
|
||||
{
|
||||
var target = CreateCorporateAction(cash: 10m);
|
||||
var source = CreateCorporateAction(cash: 0m);
|
||||
|
||||
InvokeMerge(target, source);
|
||||
|
||||
Assert.AreEqual(0m, target.GiveCashAmount);
|
||||
}
|
||||
|
||||
private static ex_dividend_info CreateCorporateAction(
|
||||
decimal cash = 0m,
|
||||
decimal giveShare = 0m,
|
||||
@@ -188,7 +199,7 @@ namespace YLErp.Modules.SwapModule
|
||||
private static void InvokeMerge(ex_dividend_info target, ex_dividend_info source)
|
||||
{
|
||||
var method = typeof(DividendService).GetMethod(
|
||||
"MergeNonZeroDividendValues",
|
||||
"MergeDividendValues",
|
||||
BindingFlags.Static | BindingFlags.NonPublic);
|
||||
Assert.IsNotNull(method, "公司行为存量合并方法不存在");
|
||||
method.Invoke(null, new object[] { target, source });
|
||||
|
||||
@@ -985,7 +985,7 @@ namespace YLErp.Modules.TradeModule.DealModule
|
||||
&& (excludedId <= 0 || O.id != excludedId));
|
||||
}
|
||||
|
||||
private static void MergeNonZeroDividendValues(ex_dividend_info target, ex_dividend_info source)
|
||||
private static void MergeDividendValues(ex_dividend_info target, ex_dividend_info source)
|
||||
{
|
||||
if (target == null)
|
||||
{
|
||||
@@ -996,26 +996,11 @@ namespace YLErp.Modules.TradeModule.DealModule
|
||||
throw new ArgumentNullException(nameof(source));
|
||||
}
|
||||
|
||||
// 同一业务键可能分别来自多行导入,或来自“数据库旧记录 + 当前导入记录”。
|
||||
// 每个字段独立合并:当前值非零时覆盖旧值,当前值为零时保留旧值,
|
||||
// 这样派息、送股、配股数量、配股价格可以从不同来源补齐到同一行。
|
||||
// 该约定将零解释为“未提供”,因此不能通过普通导入把已有字段显式清零。
|
||||
if (source.GiveCashAmount != 0m)
|
||||
{
|
||||
// 数值字段(包括 0)都是有效的覆盖值。
|
||||
target.GiveCashAmount = source.GiveCashAmount;
|
||||
}
|
||||
if (source.GiveShareAmount != 0m)
|
||||
{
|
||||
target.GiveShareAmount = source.GiveShareAmount;
|
||||
}
|
||||
if (source.RationedSharesAmount != 0m)
|
||||
{
|
||||
target.RationedSharesAmount = source.RationedSharesAmount;
|
||||
}
|
||||
if (source.RationedSharesPrice != 0m)
|
||||
{
|
||||
target.RationedSharesPrice = source.RationedSharesPrice;
|
||||
}
|
||||
if (source.Split.HasValue)
|
||||
{
|
||||
// Split 为空表示本次未提供,不能按历史兼容值 1 清空或覆盖旧倍数;明确提供 1 才覆盖。
|
||||
@@ -1098,7 +1083,7 @@ namespace YLErp.Modules.TradeModule.DealModule
|
||||
}
|
||||
|
||||
// 先在当前批次内按业务键归并。第一条记录作为待保存目标,后续记录
|
||||
// 只补充/覆盖非零字段,不会因为重复行而生成多条数据库记录。
|
||||
// 后续同一业务键记录会覆盖字段值,不会因此生成多条数据库记录。
|
||||
if (preparedIndexes.TryGetValue(businessKey, out var preparedIndex))
|
||||
{
|
||||
var preparedItem = preparedInfos[preparedIndex].Item;
|
||||
@@ -1111,7 +1096,7 @@ namespace YLErp.Modules.TradeModule.DealModule
|
||||
return false;
|
||||
}
|
||||
|
||||
MergeNonZeroDividendValues(preparedItem, item);
|
||||
MergeDividendValues(preparedItem, item);
|
||||
if (item.id > 0)
|
||||
{
|
||||
recordKeys[item.id] = businessKey;
|
||||
@@ -1175,10 +1160,7 @@ namespace YLErp.Modules.TradeModule.DealModule
|
||||
dividend.UnderlyingCode = item.UnderlyingCode;
|
||||
dividend.UnderlyingId = item.UnderlyingId;
|
||||
dividend.ExDividendDate = item.ExDividendDate;
|
||||
// 数据库已有记录也必须走与批次内重复行相同的合并规则:导入字段非零
|
||||
// 才覆盖旧值,导入字段为零则保留数据库存量值,避免一次不完整导入
|
||||
// 把旧的派息/送股/配股信息误清零。
|
||||
MergeNonZeroDividendValues(dividend, item);
|
||||
MergeDividendValues(dividend, item);
|
||||
dividend.ValidStatus = true;
|
||||
dividend.DataSource = ExDividendDataSources.Manual;
|
||||
dividend.SourceUpdatedAt = sourceUpdatedAt;
|
||||
|
||||
Reference in New Issue
Block a user