186 lines
9.2 KiB
C#
186 lines
9.2 KiB
C#
using NPOI.HPSF;
|
||
using OfficeOpenXml;
|
||
using Qdp.Pricing.Core.Modules;
|
||
using Qdp.Pricing.Library.Base.Utilities;
|
||
using System;
|
||
using System.Collections.Generic;
|
||
using System.Linq;
|
||
using System.Text;
|
||
using System.Threading.Tasks;
|
||
using YLErp.BLL;
|
||
using YLErp.Core.Helpers;
|
||
using YLErp.DBModels;
|
||
using YLErp.DBModels.Consts;
|
||
using YLErp.Model;
|
||
using YLErp.Models;
|
||
using YLErp.Modules.TradeDalModule;
|
||
using YLErp.Office;
|
||
using YLErp.Plugins.TradeDocGenerator.Abstracts;
|
||
using static YLErp.ConsGlobal;
|
||
|
||
namespace YLErp.Modules.TradeModule.DocGenerateModule
|
||
{
|
||
public class SwapSettlementBillGenerateService : YLBaseService
|
||
{
|
||
public SwapSettlementBillGenerateService(OptUserInfo userInfo) : base(userInfo)
|
||
{
|
||
}
|
||
/// <summary>
|
||
/// 生成结算确认书
|
||
/// </summary>
|
||
public IEnumerable<TradeDocGenerateResult> Generate(IEnumerable<long> flowEventIds, string docType, int userId, string userName)
|
||
{
|
||
if (docType == null)
|
||
{
|
||
throw new ArgumentNullException(nameof(docType));
|
||
}
|
||
var flowEvents = DbContext.swap_flow_event.Where(l => flowEventIds.Contains(l.id)).ToList();
|
||
var clientIds= flowEvents.Select(l => l.ClientId).ToList();
|
||
var eventDates= flowEvents.Select(l => l.UnwindDate).ToList();
|
||
var flowEventQuery = DbContext.swap_flow_event.Where(l => clientIds.Contains(l.ClientId) && eventDates.Contains(l.UnwindDate) && l.EventType == (int)SwapEventTypeEnum.平仓&&l.PositionType>0);
|
||
var newFlowEvents =from se in flowEventQuery
|
||
join s in DbContext.swap_event on se.EventId equals s.id
|
||
where s.Invalid==false
|
||
select se;
|
||
var eventIds = newFlowEvents.Select(l => l.EventId).ToList();
|
||
var tradeIds = newFlowEvents.Select(l => l.SwapTradeId).ToList();
|
||
if (tradeIds.Count() == 0)
|
||
{
|
||
throw new ArgumentNullException(nameof(tradeIds));
|
||
}
|
||
var trades = DbContext.trade.Where(x => tradeIds.Contains(x.id)).ToList();
|
||
var swapPositions = DbContext.swap_position.Where(x => tradeIds.Contains(x.SwapTradeId) && !x.Invalid).ToList();
|
||
var allFlowEvents = DbContext.swap_flow_event.Where(x => eventIds.Contains(x.EventId)).ToList();
|
||
var tradeContracts = DbContext.trade_contract_r.Where(x=> tradeIds.Contains(x.TradeId)&&x.Type== ContractTypeEnum.Clearing&&x.IsValid).ToList();
|
||
flowEvents = newFlowEvents.ToList();
|
||
// 定位要点:生成范围按【客户+平仓日】扩张——传入的是用户勾选的 flowEventIds,
|
||
// 实际生成会包含同客户同日全部平仓流水(PositionType>0)。若某笔交易未生成过交易确认书,
|
||
// TradeSettleBillGenerator 会整批抛"XX未生成交易确认书",此日志用于对齐"勾选了什么 vs 实际生成什么"。
|
||
LogFactory.GetLogger("GenerateSingleV2").Info(
|
||
$"生成结算确认书-生成范围: 传入flowEventIds[{string.Join(",", flowEventIds)}] " +
|
||
$"扩张后待生成[{string.Join(",", flowEvents.Select(f => $"{f.id}:{f.SwapTradeNo}"))}]");
|
||
//----------------------------------
|
||
// 交易确认书数据
|
||
//----------------------------------
|
||
var tcrQuery = from aa in DbContext.trade_contract_r
|
||
where tradeIds.Contains(aa.TradeId)
|
||
&& aa.Type == ContractTypeEnum.Trade && aa.IsValid
|
||
select aa;
|
||
var tcrDatas = tcrQuery.ToDictionary(K => K.TradeId, V => V);
|
||
|
||
//----------------------------------
|
||
// 生成交易结算书
|
||
//----------------------------------
|
||
var resultList = new List<TradeDocGenerateResult>();
|
||
AppManager.TryResolve(out ITradeSettleBillGenerator generatorV2);
|
||
Dictionary<int, List<swap_flow_event>> noDMAFlows = new Dictionary<int, List<swap_flow_event>>();
|
||
List<trade_extend> extendList = null;
|
||
if (flowEvents != null && flowEvents.Any())
|
||
{
|
||
var flowTradeIds = flowEvents.Where(p => p.PayDate == null || p.EventType != (int)SwapEventTypeEnum.平仓).Select(p => p.SwapTradeId).Distinct().ToList();
|
||
if (flowTradeIds != null && flowTradeIds.Count > 0)
|
||
{
|
||
extendList = DbContext.trade_extend.AsNoTracking().Where(p => flowTradeIds.Contains(p.TradeId)).ToList();
|
||
}
|
||
}
|
||
if (extendList == null)
|
||
{
|
||
extendList = new List<trade_extend>();
|
||
}
|
||
foreach (var flowEvent in flowEvents)
|
||
{
|
||
var contract = tradeContracts.FirstOrDefault(x=>x.SwapFlowEventId==flowEvent.id);
|
||
if (contract!=null)
|
||
{
|
||
continue;
|
||
}
|
||
//重置payDate 解决系统除平仓外其余场景 payDate可能为空的情况
|
||
if (flowEvent.PayDate == null || flowEvent.EventType != (int)SwapEventTypeEnum.平仓)
|
||
{
|
||
var extend = extendList.FirstOrDefault(p => p.TradeId == flowEvent.SwapTradeId);
|
||
if (extend != null)
|
||
{
|
||
flowEvent.PayDate = flowEvent.UnwindDate.Value.AddDays(extend.ExtendObj.SettlementRules);
|
||
}
|
||
}
|
||
var trade = trades.FirstOrDefault(x => x.id == flowEvent.SwapTradeId);
|
||
if (trade == null)
|
||
{
|
||
throw new ServiceException("找不到交易");
|
||
}
|
||
if (trade.ValidState!=ConsGlobal.InValid)
|
||
{
|
||
if (noDMAFlows.ContainsKey(trade.ClientId))
|
||
{
|
||
noDMAFlows[trade.ClientId].Add(flowEvent);
|
||
}
|
||
else
|
||
{
|
||
noDMAFlows[trade.ClientId] = new List<swap_flow_event> { flowEvent };
|
||
}
|
||
}
|
||
|
||
|
||
}
|
||
if (noDMAFlows.Count()==0)
|
||
{
|
||
throw new ServiceException("没有需要生成的确认书");
|
||
}
|
||
foreach (var item in noDMAFlows)
|
||
{
|
||
var noDMAResults = GenerateShanxiSwap(item.Key, item.Value, trades, swapPositions, allFlowEvents, generatorV2, docType);
|
||
resultList.AddRange(noDMAResults);
|
||
}
|
||
return resultList;
|
||
}
|
||
|
||
public void DelDoc(List<long> flowEventIds)
|
||
{
|
||
if (flowEventIds.Count==0)
|
||
{
|
||
return;
|
||
}
|
||
var tradeContracts = DbContext.trade_contract_r.Where(x => flowEventIds.Contains(x.SwapFlowEventId??0) && x.Type == ContractTypeEnum.Clearing && x.IsValid).ToList();
|
||
var contractCodes = tradeContracts.Select(s=>s.ContractCode).Distinct().ToList();
|
||
tradeContracts= DbContext.trade_contract_r.Where(x => contractCodes.Contains(x.ContractCode)).ToList();
|
||
var contractDocs = DbContext.trade_contract_document.Where(x => contractCodes.Contains(x.Code)).ToList();
|
||
DbContext.trade_contract_document.RemoveRange(contractDocs);
|
||
DbContext.trade_contract_r.RemoveRange(tradeContracts);
|
||
DbContext.SaveChanges();
|
||
}
|
||
private List<TradeDocGenerateResult> GenerateShanxiSwap(int clientId, List<swap_flow_event> flowEvents, List<trade> trades, List<swap_position> swapPositions, List<swap_flow_event> allFlowEvents, ITradeSettleBillGenerator generator,string docType)
|
||
{
|
||
var client = DataCacheProvider.GetClientDataSource().GetData(clientId);
|
||
if (client == null)
|
||
{
|
||
throw new ServiceException("未找到客户信息");
|
||
}
|
||
List<TradeDocGenerateResult> docGenerateResults = new List<TradeDocGenerateResult>();
|
||
foreach (var flowEvent in flowEvents.GroupBy(x => x.UnwindDate))//每个客户没日只有一份结算确认书
|
||
{
|
||
var flowEventGroups = flowEvent.ToList();
|
||
var tradeIds = flowEventGroups.Select(l => l.SwapTradeId).ToList();
|
||
var _trades = trades.Where(x=> tradeIds.Contains(x.id)).ToList();
|
||
try
|
||
{
|
||
var context = new SettlementBillGenerateContext(client, flowEventGroups, allFlowEvents, _trades, swapPositions, ContractTypeEnum.Clearing, OptUser);
|
||
generator.Initialize(docType, context);
|
||
var results= generator.GenerateDocuments();
|
||
docGenerateResults.AddRange(results);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
LogFactory.GetLogger("GenerateSingleV2").Error(ex);
|
||
return new List<TradeDocGenerateResult>() {new TradeDocGenerateResult(_trades)
|
||
{
|
||
Exception = ex,
|
||
ErrorMessage = "出错:" + ex.Message
|
||
} };
|
||
}
|
||
}
|
||
|
||
return docGenerateResults;
|
||
}
|
||
}
|
||
}
|