From 1c879c0b65d1f58bf970eabf28d791c25b01e095 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=A0=E5=90=8D=E9=94=90?= <1565842059@qq.com> Date: Wed, 26 Aug 2026 11:09:12 +0800 Subject: [PATCH] =?UTF-8?q?fix(trade):=20=E6=A0=87=E7=9A=84=E9=99=A4?= =?UTF-8?q?=E6=9D=830=E8=A6=86=E7=9B=96=E6=97=A7=E5=80=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 重命名 MergeNonZeroDividendValues 方法为 MergeDividendValues - 修改合并逻辑,数值字段(包括 0)都作为有效覆盖值进行合并 - 更新注释说明合并规则的变化 - 添加零现金分红覆盖现有值的单元测试 - 修复数据库记录合并时的字段覆盖逻辑 --- .../SwapModule/SplitCorporateActionTddTest.cs | 13 ++++++- .../TradeModule/DealModule/DividendService.cs | 36 +++++-------------- 2 files changed, 21 insertions(+), 28 deletions(-) diff --git a/UnitTestProject/Modules/SwapModule/SplitCorporateActionTddTest.cs b/UnitTestProject/Modules/SwapModule/SplitCorporateActionTddTest.cs index 2cd6ba1f..d7f12635 100644 --- a/UnitTestProject/Modules/SwapModule/SplitCorporateActionTddTest.cs +++ b/UnitTestProject/Modules/SwapModule/SplitCorporateActionTddTest.cs @@ -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 }); diff --git a/YLErpDAL/Modules/TradeModule/DealModule/DividendService.cs b/YLErpDAL/Modules/TradeModule/DealModule/DividendService.cs index 1deac603..399af463 100644 --- a/YLErpDAL/Modules/TradeModule/DealModule/DividendService.cs +++ b/YLErpDAL/Modules/TradeModule/DealModule/DividendService.cs @@ -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) - { - 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; - } + // 数值字段(包括 0)都是有效的覆盖值。 + target.GiveCashAmount = source.GiveCashAmount; + target.GiveShareAmount = source.GiveShareAmount; + target.RationedSharesAmount = source.RationedSharesAmount; + 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;