Files
zszq-trs/YLErpDAL/Modules/SuperviseReportModule/SAC/Service/ReportSwapConfirmationAttService.cs
T
2024-05-09 14:06:26 +08:00

620 lines
30 KiB
C#

using System.Data;
using YieldChain.Helpers;
using YLErp.BLL;
using YLErp.DBModels.Consts;
using YLErp.DBModels.Enums;
using YLErp.Modules.SuperviseReportModule.SAC.Common;
using YLErp.Modules.SuperviseReportModule.SAC.Model;
using static YLErp.DBModels.Consts.ConsReport;
namespace YLErp.Modules.SuperviseReportModule.SAC.Service
{
class ReportSwapConfirmationAttService : ReportBaseService
{
public ReportSwapConfirmationAttService(OptUserInfo optUser) : base(optUser)
{
}
protected override string _excelDataSourcePath => "交易相关\\";
protected override string _excelDataSourceFileName => "import_SwapConfirmationAtt_template.xlsx";
protected override DataFlagsEnum BusiDataType => DataFlagsEnum.A1017;
private List<OptFlagsEnum> _validOperationType = null;
public override List<OptFlagsEnum> ValidOperationType
{
get
{
if (_validOperationType == null)
{
_validOperationType = new List<OptFlagsEnum>() {
OptFlagsEnum.A,
OptFlagsEnum.U,
OptFlagsEnum.D,
};
}
return _validOperationType;
}
}
protected override SuperviseReportTypeEnum ReportType => SuperviseReportTypeEnum.SAC_ConfirmationAtt;
List<SACReportNotes> noteList = new List<SACReportNotes>();
protected override BodyModel GenerateBody(out bool noData, out List<string> fileList)
{
fileList = new List<string>();
BodyModel model = new BodyModel();
var cacheKey = $"{BusiDataType}";
List<SwapConfirmationAttModel> dataList = new List<SwapConfirmationAttModel>();
if ((PS.Config.ErpElement.SAC_ReportDataSource & SAC_ReportDataSourceEnum.Template) == SAC_ReportDataSourceEnum.Template)
{
dataList = GetSwapConfirmationAttModel(out fileList);
}
if ((PS.Config.ErpElement.SAC_ReportDataSource & SAC_ReportDataSourceEnum.System) == SAC_ReportDataSourceEnum.System)
{
var nextDate = _reqInfo.ReportDate.AddDays(1);
var nextDataDate = _reqInfo.DataDate.AddDays(1);
using (var db = new YLContext())
{
var codeList = ReportStatus.GetCacheInfo(cacheKey);
var query = (from t in db.trade
join tc in db.trade_cash
on t.id equals tc.TradeId
join tr in db.trade_contract_r
on tc.id equals tr.TradeCashId
join td in db.trade_contract_document
on tr.ContractCode equals td.Code
join ts in db.trade_swap
on t.id equals ts.TradeId
where
((_operationType == OptFlagsEnum.A && t.TradeDate >= _reqInfo.DataDate && t.TradeDate < nextDataDate)//新增时使用交易日期判断
|| (_operationType != OptFlagsEnum.A && tc.OptDate >= _reqInfo.ReportDate && tc.OptDate < nextDate)//补正和废止时使用操作日期判断
|| tr.OptDate >= _reqInfo.DataDate)
&& (_operationType == OptFlagsEnum.D || (t.ValidState != "InValid" && tc.ValidState != "InValid" && !tc.IsDeleted && tr.IsValid))
&& /*t.UnderlyingInstrumentType == "Stock" &&*/ t.TradeType == "收益互换"
&& tc.Action == "系统操作-期权费"
select new
{
tcId = tc.id,
tc.OptDate,
tradeValid = t.ValidState != "InValid",
tradecashValid = tc.ValidState != "InValid" && !tc.IsDeleted,
tradeContractRValid = tr.IsValid,
t.id,
t.ClientId,
t.TradeDate,
t.ExerciseDate,
t.SettlementDate,
t.ExerciseMode,
t.BuySell,
TradeType = t.StructureType ?? t.TradeType,
t.OptionType,
t.OriginalStockEqvNotional,
t.StockEqvNotionalReal,
t.IsMoneynessOption,
t.SpotPrice,
t.Strike,
t.MarginTemplateName,
t.MarginType,
t.InitialMargin,
t.UnderlyingCode,
t.AnnualizeFactor,
ts.IsGetFloatingProfit,
ts.IsPayFloatingProfit,
ts.GetVarietyId,
ts.PayVarietyId,
ts.GetUnderlyingCode,
ts.PayUnderlyingCode,
ts.GetLongShort,
ts.PayLongShort,
ts.GetSpotPrice,
ts.PaySpotPrice,
ts.GetTradePrice,
ts.PayTradePrice,
ts.GetSwapTimeAndRate,
ts.PaySwapTimeAndRate,
ts.GetFixedProfit,
ts.PayFixedProfit,
ts.GetMarginRate,
ts.PayMarginRate,
ts.GetTradeAmount,
ts.PayTradeAmount,
tr.ContractCode,
td.Paths,
td.StampDocumentFileName,
t.QuoteCurrency,
t.SettlementCurrency,
ts.GetUnAnnualRate,
ts.GetSingleFee,
ts.PayUnAnnualRate,
ts.PaySingleFee,
}).OrderBy(O => O.OptDate).ToArray().Where(O => !codeList.Contains(O.id + "")).ToArray();
List<int> ids = query.Select(O => O.id).ToList();
List<int> delIds = new List<int>();
if (_operationType == OptFlagsEnum.D)
{
delIds = DbContext.TradeAuditLog.Where(O => ids.Contains(O.TradeId) && O.OptDate >= _reqInfo.ReportDate && O.OptDate < nextDate && O.OptType == "删除交易").Select(O => O.TradeId).ToList();
}
Dictionary<int, Dictionary<string, string>> metaDic = DbContext.TradeMeta.Where(O => ids.Contains(O.TradeId)).AsEnumerable().GroupBy(O => O.TradeId).ToDictionary(K => K.Key, V => V.ToDictionary(K1 => K1.MetaKey, V1 => V1.MetaValue));
Dictionary<string, string> reportDescDic = DbContext.AppConfig.Where(O => O.PGroup == ConsAppConfig.ReportDescSwap).ToDictionary(K => K.PName, V => V.PValue);
foreach (var item in query)
{
var cacheValue = item.id.ToString();
if (ReportStatus.CheckCacheInfo(cacheKey, cacheValue))
{
continue;
}
//如果存在重复数据,则始终用较新的数据
SwapConfirmationAttModel info = new SwapConfirmationAttModel();
info.ConfirmationNo = item.ContractCode;
var confirmationNote = base.GetReportNotes(SuperviseReportTypeEnum.SAC_SwapConfirmation, $"_{info.ConfirmationNo.Replace("_", "-")}_").FirstOrDefault();
var currentCodes = ReportStatus.GetCacheInfo(DataFlagsEnum.A1005.ToString());//取出这一次报送交易要素的交易编号
if (!currentCodes.Contains(item.id.ToString()) && (confirmationNote == null || !confirmationNote.ReportResponse))
{
continue;//跳过交易要素还没报送的确认书附件;
}
SACReportNotes note = base.GetReportNotes(formatInfoTag(info)).FirstOrDefault();
if (note == null && _operationType == OptFlagsEnum.A)
{
info.OperationType = OptFlagsEnum.A;
note = new SACReportNotes()
{
IsValid = true,
};
}
else
{
if (note == null)
{
continue;
}
switch (_operationType)
{
case OptFlagsEnum.A:
continue;//新增数据已报送,跳过
case OptFlagsEnum.U:
if (!note.changeStatus)
{
continue;//交易没有被修改过,跳过
}
info.OperationType = OptFlagsEnum.U;
note.IsValid = true;
break;
case OptFlagsEnum.D:
if (!delIds.Contains(item.id))
{
continue;//交易没有被删除,跳过
}
info.OperationType = OptFlagsEnum.D;
note.IsValid = false;
break;
case OptFlagsEnum.NONE:
default:
throw new ServiceException("未知操作类型");
}
}
Dictionary<string, string> reportCacheDic = JsonHelper.ToObject<Dictionary<string, string>>(note.InfoCache) ?? new Dictionary<string, string>();
if (info.OperationType != _operationType)
{
continue;
}
if (info.OperationType != OptFlagsEnum.D && (!item.tradeValid || !item.tradecashValid || !item.tradeContractRValid))
{//非废止报送中,应跳过所有存在无效数据的数据
continue;
}
if (metaDic.ContainsKey(item.id))
{
var metaInfo = metaDic[item.id];
var tradingPlace = metaInfo.ContainsKey(ConsTradeMetaKey.TradingPlace) ? TradingPlaceMap[metaInfo[ConsTradeMetaKey.TradingPlace]] : "";
if (tradingPlace == "1")//跳过交易场所为报价系统的交易;
{
continue;
}
}
if (info.OperationType != OptFlagsEnum.A)
{
info.BizID = note.BizId;//确认书编号;
}
string path = item.StampDocumentFileName ?? item.Paths;
if (!path.StartsWith("\\") || path.StartsWith("/"))
{
path = "\\" + path;
}
var absolutePath = OtcAppContext.MapPath(path);
absolutePath = Path.ChangeExtension(absolutePath, "pdf");
info.ConfirmationFilesTuple = new List<ConfirmationFilesTupleModel>() { new ConfirmationFilesTupleModel() { ConfirmationFiles = Path.GetFileName(absolutePath) } };
info.ExceID = base.formatExceID();
if (!ReportStatus.CheckFileLength(absolutePath))
{
break;
}
fileList.Add(absolutePath);
ReportStatus.AddCacheInfo(cacheKey, cacheValue);
dataList.Add(info);
note.id = 0;
note.InfoCache = $"{{\"DueDate\":\"{item.OptDate?.ToString("yyyy-MM-dd")}\",\"Tag\":\"{info.ConfirmationNo}\",\"Source\":\"System\"}}";
note.ExceId = info.ExceID;
note.CreateTime = DateTime.Now;
note.FileTag = FileTag;
note.ReportType = ReportType;
note.ReportDate = _reqInfo.ReportDate;
note.InfoTag = formatInfoTag(info, true);
note.OptTime = note.CreateTime;
note.RetCode = "";
note.RetMsg = "";
note.ReportResponse = false;
note.DataId = item.tcId.ToString();
note.BizId = "";
note.changeStatus = false;
noteList.Add(note);
}
}
}
if ((PS.Config.ErpElement.SAC_ReportDataSource & SAC_ReportDataSourceEnum.KingstarView) == SAC_ReportDataSourceEnum.KingstarView)
{
dataList.AddRange(GetSwapConfirmationAttModelFromView(out fileList));
}
var subsystemDataList = loadSubsystemDataSource<SwapConfirmationAttModel>(fileList, AddSubsystemNote);
if (subsystemDataList != null && subsystemDataList.Count > 0)
dataList.AddRange(subsystemDataList);
noData = dataList.Count == 0;
model.ConfirmationAtt = dataList;
return model;
}
public bool AddSubsystemNote(SwapConfirmationAttModel model, List<string> fileList, string tag)
{
SACReportNotes note = base.GetReportNotes(ReportType, formatInfoTag(model, true)).FirstOrDefault();//参数true要加,要不A和D会查到同一条记录,在D时候,就会和A相同的数据
if (note == null)
{
note = new SACReportNotes()
{
InfoCache = $"{{\"Tag\":\"{model.ConfirmationNo}\",\"Source\":\"Subsystem\",\"SubFileTag\":\"{tag}\",\"ExceID\":\"{model.ExceID}\"}}",
IsValid = true,
};
}
else
{
switch (model.OperationType)
{
case OptFlagsEnum.A:
return false;//新增数据已报送,跳过
case OptFlagsEnum.U:
//多次U的时候,每次用最新的tag来赋值SubFileTag
note.InfoCache = $"{{\"Tag\":\"{model.ConfirmationNo}\",\"Source\":\"Subsystem\",\"SubFileTag\":\"{tag}\",\"ExceID\":\"{model.ExceID}\"}}";
note.IsValid = true;
break;
case OptFlagsEnum.D:
note.IsValid = false;
break;
case OptFlagsEnum.NONE:
default:
throw new ServiceException("未知操作类型");
}
}
if (model.ConfirmationFilesTuple != null && model.ConfirmationFilesTuple.Count > 0)
{
fileList.AddRange(model.ConfirmationFilesTuple.Select(x => x.ConfirmationFiles));
}
model.ExceID = base.formatExceID();
note.id = 0;
note.ExceId = model.ExceID;
note.CreateTime = DateTime.Now;
note.FileTag = FileTag;
note.ReportType = ReportType;
note.ReportDate = _reqInfo.ReportDate;
note.InfoTag = formatInfoTag(model, true);
note.OptTime = note.CreateTime;
note.RetCode = "";
note.RetMsg = "";
note.ReportResponse = false;
note.BizId = "";
note.changeStatus = false;
noteList.Add(note);
return true;
}
private List<SwapConfirmationAttModel> GetSwapConfirmationAttModel(out List<string> fileList)
{
fileList = new List<string>();
List<SwapConfirmationAttModel> result = new List<SwapConfirmationAttModel>();
if (_excelDataSource != null && _excelDataSource.Tables.Contains("收益互换确认书附件明细"))
{
var cacheKey = $"{BusiDataType}";
DataTable dt = _excelDataSource.Tables["收益互换确认书附件明细"];
string sourcePath = Path.Combine(_excelDataSourceRootPath, "附件");
for (int i = 1; i < dt.Rows.Count; i++)
{
if (string.IsNullOrWhiteSpace(dt.Rows[i][0]?.ToString()))
{
//第一列空白说明数据结束了;
break;
}
var optType = OptFlagsEnum.NONE;
switch (dt.Rows[i][1]?.ToString())
{
case "首次":
optType = OptFlagsEnum.A;
break;
case "变更":
optType = OptFlagsEnum.U;
break;
case "废止":
optType = OptFlagsEnum.D;
break;
}
if (optType != _operationType)
{
continue;
}
SwapConfirmationAttModel model = new SwapConfirmationAttModel();
model.ConfirmationNo = GetDataSetValue(dt, i, 0);
model.OperationType = optType;
var cacheValue = model.ConfirmationNo;
if (ReportStatus.CheckCacheInfo(cacheKey, cacheValue))
{
continue;
}
model.ConfirmationFilesTuple = new List<ConfirmationFilesTupleModel>();
var files = GetDataSetValue(dt, i, 2).Split(',');
foreach (var f in files)
{
if (!string.IsNullOrWhiteSpace(f))
{
var path = Path.Combine(sourcePath, f);
if (!ReportStatus.CheckFileLength(path))
{
break;
}
fileList.Add(path);
model.ConfirmationFilesTuple.Add(new ConfirmationFilesTupleModel() { ConfirmationFiles = f });
}
}
List<SACReportNotes> notes = base.GetReportNotes(ReportType, formatInfoTag(model));
var note = notes.LastOrDefault(O => O.InfoCache.Contains(cacheValue));
if (note == null && _operationType == OptFlagsEnum.A)
{
note = new SACReportNotes()
{
InfoCache = $"{{\"Tag\":\"{model.ConfirmationNo}\",\"Source\":\"Template\"}}",
IsValid = true,
};
}
else
{
if (note == null)
{
continue;
}
switch (_operationType)
{
case OptFlagsEnum.A:
continue;//新增数据已报送,跳过
case OptFlagsEnum.U:
note.IsValid = true;
break;
case OptFlagsEnum.D:
note.IsValid = false;
break;
case OptFlagsEnum.NONE:
default:
throw new ServiceException("未知操作类型");
}
}
if (_operationType != OptFlagsEnum.A)
{
model.BizID = note.BizId;
}
model.ExceID = base.formatExceID();
result.Add(model);
ReportStatus.AddCacheInfo(cacheKey, cacheValue);
note.id = 0;
note.ExceId = model.ExceID;
note.CreateTime = DateTime.Now;
note.FileTag = FileTag;
note.ReportType = ReportType;
note.ReportDate = _reqInfo.ReportDate;
note.InfoTag = formatInfoTag(model, true);
note.OptTime = note.CreateTime;
note.RetCode = "";
note.RetMsg = "";
note.ReportResponse = false;
note.BizId = "";
note.DataId = "";
note.changeStatus = false;
noteList.Add(note);
}
}
return result;
}
private List<SwapConfirmationAttModel> GetSwapConfirmationAttModelFromView(out List<string> fileList)
{
fileList = new List<string>();
List<SwapConfirmationAttModel> result = new List<SwapConfirmationAttModel>();
if (_viewDataSource != null && _viewDataSource.Tables.Contains("交易确认书附件"))
{
var ftpHelper = new FtpHelper(PS.Config.ErpElement.KingstarView_RemotePath, PS.Config.ErpElement.KingstarView_RemoteUser, PS.Config.ErpElement.KingstarView_RemotePassword, PS.Config.ErpElement.KingstarView_FtpUsePassive, 3000, PS.Config.ErpElement.KingstarView_EnableSsl);
var cacheKey = $"{BusiDataType}";
DataTable dt = _viewDataSource.Tables["交易确认书附件"];
for (int i = 0; i < dt.Rows.Count; i++)
{
var optType = OptFlagsEnum.NONE;
switch (GetDataSetValue(dt, i, "OPERATIONTYPE"))
{
case "A":
optType = OptFlagsEnum.A;
break;
case "U":
optType = OptFlagsEnum.U;
break;
case "D":
optType = OptFlagsEnum.D;
break;
}
if (optType != _operationType)
{
continue;
}
SwapConfirmationAttModel model = new SwapConfirmationAttModel();
model.IgnoreCheck = true;
model.ConfirmationNo = GetDataSetValue(dt, i, "CONFIRMATIONNO");
model.OperationType = optType;
var cacheValue = model.ConfirmationNo;
if (ReportStatus.CheckCacheInfo(cacheKey, cacheValue))
{
continue;
}
model.ConfirmationFilesTuple = new List<ConfirmationFilesTupleModel>();
;
var files = GetDataSetValue(dt, i, "CONFIRMATIONFILES").Split(',');
foreach (var f in files)
{
if (!string.IsNullOrWhiteSpace(f))
{
var downloadRet = ftpHelper.DownloadFile(CreateViewAttDownloadPath(f), ViewLocalAttFileDir + @"\kingstar\", out string message);
LogFactory.GetLogger("ftpHelper.DownloadFile").Info($"下载结果:{ViewLocalAttFileDir},{f},{downloadRet}");
var path = downloadRet;
if (!ReportStatus.CheckFileLength(path))
{
break;
}
fileList.Add(path);
model.ConfirmationFilesTuple.Add(new ConfirmationFilesTupleModel() { ConfirmationFiles = Path.GetFileName(path) });
}
}
List<SACReportNotes> notes = base.GetReportNotes(ReportType, formatInfoTag(model));
var note = notes.LastOrDefault(O => O.InfoCache.Contains(cacheValue));
if (note == null && _operationType == OptFlagsEnum.A)
{
note = new SACReportNotes()
{
InfoCache = $"{{\"Tag\":\"{model.ConfirmationNo}\",\"Source\":\"KingstarView\"}}",
IsValid = true,
};
}
else
{
if (note == null)
{
continue;
}
switch (_operationType)
{
case OptFlagsEnum.A:
continue;//新增数据已报送,跳过
case OptFlagsEnum.U:
note.IsValid = true;
break;
case OptFlagsEnum.D:
note.IsValid = false;
break;
case OptFlagsEnum.NONE:
default:
throw new ServiceException("未知操作类型");
}
}
if (_operationType != OptFlagsEnum.A)
{
model.BizID = note.BizId;
}
model.ExceID = base.formatExceID();
result.Add(model);
ReportStatus.AddCacheInfo(cacheKey, cacheValue);
note.id = 0;
note.ExceId = model.ExceID;
note.CreateTime = DateTime.Now;
note.FileTag = FileTag;
note.ReportType = ReportType;
note.ReportDate = _reqInfo.ReportDate;
note.InfoTag = formatInfoTag(model, true);
note.OptTime = note.CreateTime;
note.RetCode = "";
note.RetMsg = "";
note.ReportResponse = false;
note.BizId = "";
note.DataId = "";
note.changeStatus = false;
noteList.Add(note);
}
}
return result;
}
private string formatInfoTag(SwapConfirmationAttModel model, bool suffixType = false)
{
string result = $"{BusiDataType}_{model.ConfirmationNo.Replace("_", "-")}_成交_确认书_";
if (suffixType)
{
result = $"{result}{_operationType}";
}
return result;
}
protected override List<SacInfo> CheckBodyValue(BodyModel model, out bool checkStatus)
{
List<SacInfo> result = new List<SacInfo>();
if (model?.ConfirmationAtt != null)
{
CheckHelper<SwapConfirmationAttModel> helper = new CheckHelper<SwapConfirmationAttModel>();
for (int i = 0; i < model.ConfirmationAtt.Count; i++)
{
List<SacInfo> listRoot = new List<SacInfo>();
var item = model.ConfirmationAtt[i];
if (item.IgnoreCheck) continue;
helper.ExecuteCheck(item, (name, value, msg) =>
{
listRoot.Add(new SacInfo(name, value, msg));
});
if (listRoot.Count > 0)
{
var errMsg = new SacInfo("SwapConfirmationAtt", i);
errMsg.SubMaps = new List<SacInfo>(listRoot);
result.Add(errMsg);
}
}
}
checkStatus = result.Count > 0;
return result;
}
public override bool BeforeOfGenerated(out string errMsg)
{
errMsg = "";
foreach (var file in xmlAttachmentList)
{
try
{
File.Delete(file);
}
catch (Exception e)
{
LogFactory.GetLogger<ReportMasterAgrmtProductService>().Error(e);
};
}
for (int i = 0; i < noteList.Count; i++)
{
base.SaveReportNotes(noteList[i]);
}
return true;
}
}
}