From 02da9d78a37fa4b8de107a874197228768fcecf1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=A0=E5=90=8D=E9=94=90?= <1565842059@qq.com> Date: Fri, 21 Aug 2026 13:50:31 +0800 Subject: [PATCH] =?UTF-8?q?refactor(EodModule):=20=E7=A7=BB=E9=99=A4?= =?UTF-8?q?=E5=80=BA=E5=88=B8=E6=94=AF=E4=BB=98=E6=9C=8D=E5=8A=A1=E4=B8=AD?= =?UTF-8?q?=E5=AF=B9=E5=85=AC=E5=8F=B8=E8=A1=8C=E4=B8=BA=E5=90=8C=E6=AD=A5?= =?UTF-8?q?=E9=95=9C=E5=83=8F=E7=9A=84=E4=BE=9D=E8=B5=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 不再依赖 bond-sync 镜像,Stock/Fund 公司行为直接作为展示行返回 - 展示金额按"每 10 份派现金额"换算为 GiveCashAmount / 10 - 添加公司行为除权表数据查询逻辑,与现有查询结果合并 - 简化债券支付服务中公司行为处理逻辑,移除去重机制 - 更新现金分红处理逻辑,统一通过 CalcBondPayment 读取 ex_dividend_info - 移除不再需要的 channel_source 和 jsid 字段设置 --- .../Modules/EodModule/BondPaymentService.cs | 55 +++++++++++++------ .../SwapModule/SwapEodPositionService.cs | 7 +-- 2 files changed, 41 insertions(+), 21 deletions(-) diff --git a/YLErpDAL/Modules/EodModule/BondPaymentService.cs b/YLErpDAL/Modules/EodModule/BondPaymentService.cs index 9605de64..e71c2e6a 100644 --- a/YLErpDAL/Modules/EodModule/BondPaymentService.cs +++ b/YLErpDAL/Modules/EodModule/BondPaymentService.cs @@ -59,7 +59,43 @@ namespace YLErp.Modules.EodModule create_time = source.create_time, update_time = source.update_time }; - var result = query.ToSearchList(req); + // 不再依赖 bond-sync 镜像:Stock/Fund 公司行为直接作为展示行返回。 + // 展示金额按“每 10 份派现金额”换算为 GiveCashAmount / 10;EOD 计算仍使用 + // GetBondPayments 的内部单位口径,不受此处展示换算影响。 + var corporateQuery = from un in queryUn + join dividend in DbContext.ex_dividend_info.AsNoTracking() + on un.UnderlyingCode equals dividend.UnderlyingCode + where dividend.ValidStatus + && dividend.EffectiveDate.HasValue + && dividend.EffectiveDate.Value >= valueDtStart + && dividend.EffectiveDate.Value < valueDtEnd + && dividend.GiveCashAmount != 0 + && (string.IsNullOrEmpty(req.UnderlyingCode) + || dividend.UnderlyingCode.Contains(req.UnderlyingCode)) + && (un.UnderlyingInstrumentType == ConsGlobal.InstrumentType.Stock + || un.UnderlyingInstrumentType == ConsGlobal.InstrumentType.Fund) + && (string.IsNullOrEmpty(req.DataSource) + || "公司行为除权表".Contains(req.DataSource)) + select new BondPaymentDto + { + id = -dividend.id, + channel_source = "公司行为除权表", + MarketName = un.MarketName, + security_id = un.UnderlyingCode, + symbol = un.UnderlyingName, + coupon_rate = null, + payment_date = dividend.EffectiveDate, + payment_interest = dividend.GiveCashAmount / 10m, + payment_parvalue = null, + paying_price = dividend.GiveCashAmount / 10m, + create_time = dividend.OptDate, + update_time = dividend.OptDate + }; + // EF Core 无法翻译两个对 BondPaymentDto 继承属性赋值集合不完全一致的投影 + // 直接 Concat;分别执行后在内存合并,不改变两组查询的筛选口径。 + var rows = query.ToList(); + rows.AddRange(corporateQuery.ToList()); + var result = rows.AsQueryable().ToSearchList(req); return result; } @@ -107,11 +143,8 @@ namespace YLErp.Modules.EodModule string.Join(",", result.Select(r => r.reg_date?.ToString("yyyy-MM-dd")))); // 让 Copy/Update EOD 始终只依赖 BondPaymentService,而不必在收盘链路直接累加 ex_dividend_info。 - // 口径约定:bond_payment_info.payment_interest 对 Stock/Fund 统一按“每 10 份派现金额”存储, - // 即直接存 ex_dividend_info.GiveCashAmount 原值,不做 /10; + // Stock/Fund 公司行为直接从 ex_dividend_info 读取,内部仍按“每 10 份派现金额”保存 GiveCashAmount 原值, // 最后的 /10 由 CalcPayment 非债券分支完成。 - // 去重:镜像任务完成后的正式记录带 jsid = -dividend.id;此处先按该负号标记, - // 或用“同一实际付息日 + 同一派现金额”兜底去重,避免镜像完成后重复计息。 var corporatePayments = (from dividend in DbContext.ex_dividend_info.AsNoTracking() join underlying in DbContext.underlying_manager.AsNoTracking() on dividend.UnderlyingCode equals underlying.UnderlyingCode @@ -128,16 +161,6 @@ namespace YLErp.Modules.EodModule { // 按“每 10 份派现金额”口径,直接存 GiveCashAmount 原值,与同步任务/CalcPayment 保持一致。 var paymentInterest = dividend.GiveCashAmount; - var hasMirroredPayment = result.Any(payment => - payment.jsid == -dividend.id - || (payment.payment_date.HasValue - && payment.payment_date.Value.Date == dividend.EffectiveDate.Value.Date - && payment.payment_interest == paymentInterest)); - if (hasMirroredPayment) - { - continue; - } - result.Add(new BondPayment { underlyingCode = dividend.UnderlyingCode, @@ -145,8 +168,6 @@ namespace YLErp.Modules.EodModule payment_date = dividend.EffectiveDate, payment_interest = paymentInterest, paying_price = paymentInterest, - channel_source = ExDividendDataSources.Manual, - jsid = -dividend.id, create_time = dividend.OptDate, update_time = dividend.OptDate }); diff --git a/YLErpDAL/Modules/SwapModule/SwapEodPositionService.cs b/YLErpDAL/Modules/SwapModule/SwapEodPositionService.cs index fc73a583..5b7944db 100644 --- a/YLErpDAL/Modules/SwapModule/SwapEodPositionService.cs +++ b/YLErpDAL/Modules/SwapModule/SwapEodPositionService.cs @@ -628,10 +628,9 @@ namespace YLErp.Modules.SwapModule preSettleDate, flowEvents); - // 现金分红不在登记日直接读取 ex_dividend_info 累加。 - // 同步任务会把 GiveCashAmount(每 10 份派现金额)写入 bond_payment_info,Copy/Update EOD 在 - // EffectiveDate 通过 CalcBondPayment 命中该行并生成 TdPosiDividend。 - // 这样登记日快照不提前变化,也不会与债券付息/平仓链路重复计算。 + // 现金分红不在登记日直接累加;Copy/Update EOD 通过 CalcBondPayment + // 读取 EffectiveDate 命中的 ex_dividend_info,并生成 TdPosiDividend。 + // 这样登记日快照不提前变化,且公司行为分红与债券付息共用同一待实现余额。 RecordCorporateActionEvents( td, curEodPosis,