fix: eod_commodity_future_price 入库前以 UnderlyingCode 重派生 UnderlyingId,防止 FR007 等价格行 UnderlyingId 与 FutureContractId 失同步
- 新增 EodPriceService.SyncUnderlyingIdFromCode:入库前以 UnderlyingCode(FutureContractId) 为准反查真实 UnderlyingId,不一致则告警并自动校正 - SaveEodFuturePrice(web编辑/新增)、SettlementPriceImportService(xlsx上传)、EodSyntheticPriceSaveService(系统合成价) 写入前调用 - 根治'网页端能查到、EOD结算查不到'的失同步问题
This commit is contained in:
@@ -1,8 +1,5 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using BaseOUDAL;
|
||||
using DocumentFormat.OpenXml.Bibliography;
|
||||
using NPOI.POIFS.NIO;
|
||||
using YLErp.BLL;
|
||||
using YLErp.Helpers;
|
||||
|
||||
namespace YLErp.Modules.EodModule
|
||||
@@ -32,6 +29,37 @@ namespace YLErp.Modules.EodModule
|
||||
return (start, end);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 校正 eod_commodity_future_price 行的 UnderlyingId,使其与 UnderlyingCode(=FutureContractId) 一致。
|
||||
/// 背景:网页日终价格列表按 UnderlyingId(int) JOIN underlying_manager,而 EOD 结算(EodPriceProvider.Initialize)
|
||||
/// 按 UnderlyingCode(string) JOIN。两列一旦失同步(典型如 FR007 的价格行 UnderlyingId 被错写成 511160.SH 的 id),
|
||||
/// 会出现"网页能查到、结算却查不到"的错价缺失,进而 EodCheckSettlePrice 报"结算价格缺失"。
|
||||
/// 这里以 UnderlyingCode 为准重新派生 UnderlyingId——该列才是上传/结算使用的自然键(FutureContractId),
|
||||
/// 在入库前强制两列一致,既阻止产生新的错行,又通过告警日志把失同步暴露给运维追查上游写入来源。
|
||||
/// </summary>
|
||||
public static void SyncUnderlyingIdFromCode(YLContext db, eod_commodity_future_price row)
|
||||
{
|
||||
if (row == null || string.IsNullOrWhiteSpace(row.UnderlyingCode))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var um = db.underlying_manager.FirstOrDefault(u => u.UnderlyingCode == row.UnderlyingCode);
|
||||
if (um == null)
|
||||
{
|
||||
// 标的代码在 underlying_manager 不存在:无法校正,交由既有"标的代码不存在"等校验处理。
|
||||
return;
|
||||
}
|
||||
|
||||
if (row.UnderlyingId != um.id)
|
||||
{
|
||||
LogFactory.GetLogger("EodPrice").Info(
|
||||
$"eod_commodity_future_price.UnderlyingId 与 UnderlyingCode 不一致,已自动校正: " +
|
||||
$"FutureContractId={row.UnderlyingCode}, 原UnderlyingId={row.UnderlyingId}, 修正为={um.id}");
|
||||
row.UnderlyingId = um.id;
|
||||
}
|
||||
}
|
||||
|
||||
public SearchListResult<EodUnderlyingPriceDto> SearchUnderlyingList(EodCommodityFuturePriceReq req)
|
||||
{
|
||||
var (valueDtStart, valueDtEnd) = ResolveValueDateWindow(req.ValueDateStart, req.ValueDateEnd);
|
||||
@@ -219,6 +247,9 @@ namespace YLErp.Modules.EodModule
|
||||
|
||||
dbmodel.DataSource = EodPriceBase.人工;
|
||||
|
||||
// 入库前强制 UnderlyingId 与 UnderlyingCode(FutureContractId) 一致,避免网页/结算两套 JOIN 失同步。
|
||||
SyncUnderlyingIdFromCode(DbContext, dbmodel);
|
||||
|
||||
DbContext.SaveChanges();
|
||||
|
||||
return dbmodel;
|
||||
|
||||
@@ -159,6 +159,9 @@ namespace YLErp.Modules.EodModule.SettlementModule
|
||||
DataSource = EodPriceBase.系统
|
||||
};
|
||||
|
||||
// 入库前强制 UnderlyingId 与 UnderlyingCode(FutureContractId) 一致,避免网页/结算两套 JOIN 失同步。
|
||||
EodPriceService.SyncUnderlyingIdFromCode(DbContext, dto.CommodityPrice);
|
||||
|
||||
DbContext.eod_commodity_future_price.Add(dto.CommodityPrice);
|
||||
}
|
||||
|
||||
|
||||
@@ -158,6 +158,8 @@ namespace YLErp.Modules.EodModule
|
||||
eodPrice.ValueDate = item.date;
|
||||
eodPrice.UnderlyingCode = underlying.UnderlyingCode;
|
||||
eodPrice.UnderlyingId = underlying.id;
|
||||
// 入库前强制 UnderlyingId 与 UnderlyingCode(FutureContractId) 一致,避免网页/结算两套 JOIN 失同步。
|
||||
EodPriceService.SyncUnderlyingIdFromCode(DbContext, eodPrice);
|
||||
if (item.closePrice.HasValue)
|
||||
eodPrice.ClosePrice = item.closePrice ?? 0;
|
||||
if (item.settlePrice.HasValue)
|
||||
|
||||
Reference in New Issue
Block a user