Files
zszq-trs/YLErpDAL/Modules/EodModule/SettlementPriceImportService.cs
T
hjhan 760ffd62e6 fix: 日终债券来源固定中债估值、人工改动显示操作人并补上传溯源
china_bond_valuation 来源恒为中债估值(聚源仅转发,无人手工维护),不再按 JSID 推断系统/人工;eod 两表仍用自带 DataSource(人工/系统)。债券被人工改动(update_user 非空)时,日终列表来源列显示操作人姓名,否则显示中债估值;操作人经已有 create_user/update_user 列溯源(零 DDL)。手工上传 xlsx 的债券分支补戳操作人,与表单编辑口径一致。配套单测 EodPriceDtoTest / EodPriceGoldenReplayTest + golden JSON。
2026-07-13 11:00:33 +08:00

243 lines
9.4 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System.Data;
using YLErp.Commons;
using YLErp.Model;
namespace YLErp.Modules.EodModule
{
/// <summary>
/// 结算价导入服务
/// </summary>
public class SettlementPriceImportService : YLBaseService
{
public SettlementPriceImportService(OptUserInfo userInfo) : base(userInfo)
{
}
/// <summary>
/// 导入xlsx数据
/// </summary>
public ImportResultModel ImportxlsxDatas(Stream stream)
{
var importModels = Enumerable.Empty<ImportModel>();
var rowIndex = 0;
try
{
var ds = Office.ExcelHelper.ReadExcelAsDataSet(stream);
if (ds.Tables.Count < 1 || ds.Tables[0].Rows.Count < 1)
{
throw new ServiceException("读取导入数据失败:数据为空") { Tag = "111" };
}
var table = ds.Tables[0];
var reader = new DataRowReader(table);
var list = new List<ImportModel>();
rowIndex = 1;
foreach (DataRow row in table.Rows)
{
rowIndex++;
if (row.ItemArray.All(n => string.IsNullOrWhiteSpace(n?.ToString())))
{
continue;
}
reader.SetDataRow(row);
var model = new ImportModel
{
date = reader.GetDate("日期", true).Value,
code = reader.GetString("代码", true),
closePrice = reader.GetDouble("收盘价", false),
settlePrice = reader.GetDouble("结算价", false),
ReferencePrice = reader.GetDouble("参考价", false)
};
model.underlying = DataCacheProvider.GetUnderlyingDataSource().GetData(model.code);
if (model.underlying == null)
{
throw new ServiceException("标的代码不存在:" + model.code) { Tag = "111" };
}
list.Add(model);
}
importModels = list.ToArray();
}
catch (ServiceException se)
{
if (se.Tag != null) throw;
throw new ServiceException($"第{rowIndex}行,发生错误:{se.Message}");
}
catch (Exception ex)
{
LogFactory.GetLogger("导入场内交易").Error(ex);
throw new ServiceException($"第{rowIndex}行,发生错误:{ex.Message}", ex);
}
if (!importModels.Any())
{
throw new ServiceException("没有可导入的数据");
}
var result = new ImportResultModel
{
TotalCount = importModels.Count()
};
var dates = new HashSet<DateTime>();
var uniqSet = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
foreach (var item in importModels)
{
var underlying = item.underlying;
if (underlying.IsBond())
{
var eodPrice = DbContext.china_bond_valuation
.FirstOrDefault(p => p.valuation_date == item.date && p.bond_id == underlying.UnderlyingCode);
if (eodPrice == null)
{
var datestr = item.date.ToString("yyyyMMdd");
if (uniqSet.Add(datestr + "^" + item.code))
{
eodPrice = new ChinaBondValuation();
eodPrice.credibility = 1;
DbContext.china_bond_valuation.Add(eodPrice);
}
else
{
result.Errors.Add($"重复数据,忽略: {datestr},{item.code}");
continue;
}
}
eodPrice.valuation_date = item.date;
eodPrice.bond_id = underlying.UnderlyingCode;
if (item.closePrice.HasValue)
eodPrice.dirty_price_close =Convert.ToDecimal(item.closePrice ?? 0);
if (item.settlePrice.HasValue)
eodPrice.net_price = Convert.ToDecimal(item.settlePrice ?? 0);
if (item.ReferencePrice.HasValue)
eodPrice.yield = Convert.ToDecimal(item.ReferencePrice);
eodPrice.update_time = DateTime.Now;
// 手工上传也是登录用户的人工动作,戳操作人到已有列(create_user/update_user)
// 使列表来源列显示上传人姓名(与 SaveBondPrice 口径一致);聚源/中债自动同步(外部ETL)不写这两列。
// eodPrice.id==0 表示本次新增(尚未落库),非0为命中已有行的更新。
EodPriceService.StampBondOperator(eodPrice, UserId, eodPrice.id == 0);
result.SuccessCount++;
}
else if (!underlying.CalcTypeIsStock())
{
var eodPrice = DbContext.eod_commodity_future_price
.FirstOrDefault(p => p.ValueDate == item.date && p.UnderlyingCode == underlying.UnderlyingCode);
if (eodPrice == null)
{
var datestr = item.date.ToString("yyyyMMdd");
if (uniqSet.Add(datestr + "^" + item.code))
{
eodPrice = new eod_commodity_future_price();
DbContext.eod_commodity_future_price.Add(eodPrice);
}
else
{
result.Errors.Add($"重复数据,忽略: {datestr},{item.code}");
continue;
}
}
eodPrice.ValueDate = item.date;
eodPrice.UnderlyingCode = underlying.UnderlyingCode;
eodPrice.UnderlyingId = underlying.id;
if (item.closePrice.HasValue)
eodPrice.ClosePrice = item.closePrice ?? 0;
if (item.settlePrice.HasValue)
eodPrice.SettlePrice = item.settlePrice ?? 0;
if (item.ReferencePrice.HasValue)
eodPrice.ReferencePrice = item.ReferencePrice;
eodPrice.OptId = UserId;
eodPrice.OptName = UserName;
eodPrice.OptDate = DateTime.Now;
eodPrice.DataSource = EodPriceBase.人工;
result.SuccessCount++;
}
else
{
var stockPrice = DbContext.eod_stock_price
.FirstOrDefault(p => p.ValueDate == item.date && p.UnderlyingCode == underlying.UnderlyingCode);
if (stockPrice == null)
{
var datestr = item.date.ToString("yyyyMMdd");
if (uniqSet.Add(datestr + "^" + item.code))
{
stockPrice = new eod_stock_price();
DbContext.eod_stock_price.Add(stockPrice);
}
else
{
result.Errors.Add($"重复数据,忽略: {datestr},{item.code}");
continue;
}
}
stockPrice.ValueDate = item.date;
stockPrice.UnderlyingCode = underlying.UnderlyingCode;
if (item.closePrice.HasValue)
stockPrice.ClosePrice = item.closePrice ?? 0;
if (item.ReferencePrice.HasValue)
stockPrice.ReferencePrice = item.ReferencePrice;
stockPrice.OptDate = DateTime.Now;
stockPrice.DataSource = EodPriceBase.人工;
result.SuccessCount++;
}
//else
//{
// result.Errors.Add("未导入,标的不属于商品或股票:" + item.code);
//}
dates.Add(item.date.Date);
}
DbContext.SaveChanges();
if (dates.Contains(BLL.valuedateBLL.ValueDate))
{
var sql = $@"
update underlying_manager um join eod_commodity_future_price eod on um.UnderlyingCode = eod.FutureContractId
set um.Price = eod.ClosePrice where eod.ValueDate='{BLL.valuedateBLL.ValueDate:yyyy-MM-dd}';
update underlying_manager um join eod_stock_price eod on um.UnderlyingCode = eod.StockId
set um.Price = eod.ClosePrice where eod.ValueDate='{BLL.valuedateBLL.ValueDate:yyyy-MM-dd}';";
DbContext.Database.ExecuteSqlRaw(sql);
}
return result;
}
class ImportModel
{
public DateTime date { get; set; }
public string code { get; set; }
public double? closePrice { get; set; }
public double? settlePrice { get; set; }
public double? ReferencePrice { get; set; }
public underlying_manager underlying { get; set; }
}
}
}