560 lines
28 KiB
C#
560 lines
28 KiB
C#
using System.Data;
|
|
using System.Text.RegularExpressions;
|
|
using YLErp.BLL;
|
|
using YLErp.BLL.MarginCalculation;
|
|
using YLErp.DBModels.Consts;
|
|
using YLErp.DBModels.Converts;
|
|
using YLErp.Model;
|
|
using YLErp.Models;
|
|
using YLErp.Modules.DataProviderModule;
|
|
using YLErp.Modules.TradeDalModule;
|
|
using YLErp.MsOffice;
|
|
using YLErp.Office;
|
|
using YLErp.Office.Converters;
|
|
using YLErp.Plugins.TradeDocGenerator.Abstracts;
|
|
|
|
namespace YLErp.Modules.TradeModule.DocGenerateModule
|
|
{
|
|
/// <summary>
|
|
/// 生成结算确认书
|
|
/// </summary>
|
|
public class SettlementBillGenerateService : YLBaseService
|
|
{
|
|
public SettlementBillGenerateService(OptUserInfo userInfo) : base(userInfo)
|
|
{
|
|
}
|
|
|
|
public SettlementBillGenerateService(YLBaseService baseService) : base(baseService)
|
|
{
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取交易关联的标的
|
|
/// </summary>
|
|
public underlying_manager GetTradeUnderlying(string underlyingcode)
|
|
{
|
|
var _underlying = DbContext.underlying_manager.AsNoTracking().FirstOrDefault(x => x.UnderlyingCode == underlyingcode);
|
|
return _underlying;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 生成结算确认书
|
|
/// </summary>
|
|
public IEnumerable<TradeDocGenerateResult> Generate(IEnumerable<int> tradeCashIds, IEnumerable<int> tradeIds, string docType, int userId, string userName)
|
|
{
|
|
if (docType == null)
|
|
{
|
|
throw new ArgumentNullException(nameof(docType));
|
|
}
|
|
|
|
if (tradeCashIds != null && tradeCashIds.Any())
|
|
{
|
|
tradeIds = DbContext.trade_cash.Where(x => tradeCashIds.Contains(x.id) && !x.IsDeleted).Select(x => x.TradeId).Distinct();
|
|
}
|
|
|
|
if (tradeIds == null)
|
|
{
|
|
throw new ArgumentNullException(nameof(tradeIds));
|
|
}
|
|
|
|
//当前交易日
|
|
var valueDate = valuedateBLL.ValueDate;
|
|
var tradeStatus = new string[] { ConsTrade.已到期, ConsTrade.已执行 };
|
|
var tradeCashStatus = new string[] { ClientCashInCashOut.系统操作_行权费, ClientCashInCashOut.系统操作_平仓费, ClientCashInCashOut.系统操作_互换, ClientCashInCashOut.系统操作_票息 };
|
|
|
|
//----------------------------------
|
|
// 获取当日行权 平仓 到期的有效交易
|
|
//----------------------------------
|
|
var service = new TradeDalService(this);
|
|
var tradeQuery = service
|
|
.GetTradeOrEodTrade(tradeIds, valueDate)
|
|
.Where(O => tradeStatus.Contains(O.TradeStatus)
|
|
&& O.UnWindDate <= valueDate
|
|
&& O.ClientId != 0);
|
|
|
|
if (PS.Config.Is浙期)
|
|
{//主要解决多腿交易,只勾选一腿时,将另一腿查出来一起生成;
|
|
tradeQuery = service
|
|
.GetTradeOrEodTradeOfTidASid(tradeIds, valueDate, useTradeDate: false)
|
|
.Where(O => tradeStatus.Contains(O.TradeStatus)
|
|
&& O.TradeType != "结构化交易"
|
|
&& O.UnWindDate <= valueDate
|
|
&& O.ClientId != 0);
|
|
}
|
|
var tradeDic = tradeQuery.ToDictionary(n => n.id, n => new trade_contract_group { trade = n });
|
|
if (tradeDic.Count < 1)
|
|
{
|
|
throw new ServiceException("当日没有要结算的记录信息!");
|
|
}
|
|
|
|
tradeIds = tradeDic.Keys.ToArray();
|
|
var parentTradeIds = tradeDic.Values.Where(O => O.trade != null && O.trade.ParentTradeId != 0).ToDictionary(K => K.trade.id, V => V.trade.ParentTradeId);
|
|
|
|
if (PS.Config.Is长江)
|
|
{
|
|
parentTradeIds = tradeDic.Values.Where(O => O.trade != null && O.trade.ParentTradeId != 0 && (O.trade.StructureType == "牛市价差" || O.trade.StructureType == "熊市价差")).ToDictionary(K => K.trade.id, V => V.trade.ParentTradeId);
|
|
}
|
|
|
|
var parentTrades = service
|
|
.GetStructTradeFromTradeOrEodTrade(parentTradeIds.Values, valueDate)
|
|
.Where(O =>
|
|
tradeStatus.Contains(O.TradeStatus)
|
|
&& O.UnWindDate <= valueDate
|
|
&& O.ClientId != 0)
|
|
.ToDictionary(K => K.id, V => V);
|
|
|
|
if (PS.Config.Is长江 && parentTrades.Count > 0)
|
|
{
|
|
tradeIds = parentTrades.Select(O => O.Key);
|
|
}
|
|
//----------------------------------
|
|
// 交易确认书数据
|
|
//----------------------------------
|
|
var tcrQuery = from aa in DbContext.trade_contract_r
|
|
where (tradeIds.Contains(aa.TradeId)
|
|
|| parentTradeIds.Values.Contains(aa.TradeId))
|
|
&& aa.Type == ContractTypeEnum.Trade && aa.IsValid
|
|
select aa;
|
|
var tcrDatas = tcrQuery.ToDictionary(K => K.TradeId, V => V);
|
|
foreach (var data in tradeDic)
|
|
{
|
|
var id = data.Key;
|
|
if (data.Value.trade.ParentTradeId != 0)
|
|
{
|
|
id = data.Value.trade.ParentTradeId;
|
|
}
|
|
if (tcrDatas.TryGetValue(id, out var tcr))
|
|
{
|
|
data.Value.ConfirmContractR = tcr;
|
|
}
|
|
}
|
|
|
|
//----------------------------------
|
|
// 交易现金交割记录
|
|
//----------------------------------
|
|
var cashQuery = from tradeCash in DbContext.trade_cash.AsNoTracking()
|
|
where tradeIds.Contains(tradeCash.TradeId)
|
|
&& tradeCash.ValidState != ConsGlobal.InValid && !tradeCash.IsDeleted
|
|
&& tradeCash.IsLastAction
|
|
//20230408:如果参数入值没问题的话,ExerciseWay应该是不需要的
|
|
//20230408:东莞的黑箱雪球的tradeCash.ExerciseWay为null,故而把这行注释掉
|
|
// tradeCash.ExerciseWay == TradeCashExerciseWayEnum.到期行权
|
|
select tradeCash;
|
|
|
|
//当一笔交易存在多条到期行权记录时,取的最后一条资金记录。 --时嬴政 2022年8月2日
|
|
var cashDatas = cashQuery.AsEnumerable().GroupBy(O => O.TradeId).ToDictionary(K => K.Key, V => V.LastOrDefault());
|
|
|
|
foreach (var data in cashDatas)
|
|
{
|
|
if (tradeDic.TryGetValue(data.Value.TradeId, out var group))
|
|
{
|
|
if (parentTradeIds.ContainsKey(data.Value.TradeId))
|
|
{
|
|
if (PS.Config.Is光大光子)//这个分支里的逻辑和下面那个长江应该没区别
|
|
{
|
|
var id = parentTradeIds[data.Value.TradeId];
|
|
var allTradeList = service.GetTradeOrEodTradeOfTidAPid(new[] { id }, valueDate).GroupBy(O => O.TradeStatus).ToDictionary(K => K.Key, V => V.ToList());
|
|
allTradeList.First().Value.RemoveAll(x => x.ParentTradeId != 0 && !tradeIds.Contains(x.id));
|
|
var subTrades = allTradeList.First().Value.Where(x => x.ParentTradeId != 0).ToList();
|
|
var subTradeIds = subTrades.Select(O => O.id);
|
|
var cashes = cashQuery.Where(O => subTradeIds.Contains(O.TradeId)).AsEnumerable().GroupBy(O => new { O.ValueDate, O.Action, O.ExerciseWay, O.Notional, O.UnwindNotional }).ToDictionary(K => K.Key, V => V.ToList());
|
|
if (subTrades.Count == cashes.First().Value.Count)
|
|
{
|
|
subTrades.ForEach(O => O.trade_cash = cashes.First().Value.First(B => B.TradeId == O.id));
|
|
group.trade = allTradeList.First().Value.Where(O => O.id == id).First();
|
|
group.trade.SubTrades = allTradeList.First().Value.Where(O => O.id != id).ToList();
|
|
}
|
|
}
|
|
else if (PS.Config.Is长江 || PS.Config.Is浙期)
|
|
{
|
|
var id = parentTradeIds[data.Value.TradeId];
|
|
//将已到期和已执行视为同一个状态;
|
|
var allTradeList = service.GetTradeOrEodTradeOfTidAPid(new[] { id }, valueDate).GroupBy(O => (O.TradeStatus == "已执行" ? "已到期" : O.TradeStatus)).ToDictionary(K => K.Key, V => V.ToList());
|
|
var subTrades = allTradeList.Values.Aggregate((X, Y) => { X.AddRange(Y); return X; }).Where(x => x.ParentTradeId != 0).ToList();
|
|
var subTradeIds = subTrades.Select(O => O.id);
|
|
var cashes = cashQuery.Where(O => subTradeIds.Contains(O.TradeId)).AsEnumerable().GroupBy(O => new { O.ValueDate, O.Action, O.ExerciseWay, O.Notional, O.UnwindNotional }).ToDictionary(K => K.Key, V => V.ToList());
|
|
//忽略主交易状态;
|
|
if (subTrades.GroupBy(O => (O.TradeStatus == "已执行" ? "已到期" : O.TradeStatus)).Count() == 1 && cashes.Count == 1)
|
|
{
|
|
subTrades.ForEach(O => O.trade_cash = cashes.First().Value.First(B => B.TradeId == O.id));
|
|
group.trade = allTradeList.First().Value.Where(O => O.id == id).First();
|
|
group.trade.SubTrades = subTrades;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
var id = parentTradeIds[data.Value.TradeId];
|
|
var subTrades = service.GetStructTradeFromTradeOrEodTrade(new[] { id }, valueDate).GroupBy(O => O.TradeStatus).ToDictionary(K => K.Key, V => V.ToList());
|
|
tradeIds = subTrades.First().Value.Select(O => O.id).ToArray();
|
|
var cashes = cashQuery.AsEnumerable().GroupBy(O => new { O.ValueDate, O.Action, O.ExerciseWay, O.Notional, O.UnwindNotional }).ToDictionary(K => K.Key, V => V.ToList());
|
|
if (subTrades.Count == 1 && cashes.Count == 1)
|
|
{
|
|
subTrades.First().Value.ForEach(O => O.trade_cash = cashes.First().Value.First(B => B.TradeId == O.id));
|
|
group.trade = parentTrades[group.trade.id];
|
|
group.trade.SubTrades = subTrades.First().Value;
|
|
}
|
|
}
|
|
}
|
|
group.trade.trade_cash = data.Value;
|
|
group.trade_cash = data.Value;
|
|
|
|
if (group.trade.TradeType == "结构化交易")
|
|
{
|
|
if (group.trade.IsGroup == 1)
|
|
{
|
|
group.trade.SubTrades = DbContext.trade.Where(O => O.ParentTradeId == group.trade.id).ToList();
|
|
foreach (var subtc in group.trade.SubTrades)
|
|
{
|
|
subtc.trade_cash = DbContext.trade_cash.FirstOrDefault(tc => tc.TradeId == subtc.id
|
|
&& tc.ValidState != ConsGlobal.InValid && !tc.IsDeleted
|
|
&& tc.IsLastAction);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//----------------------------------
|
|
// 生成交易结算书
|
|
//----------------------------------
|
|
var resultList = new List<TradeDocGenerateResult>();
|
|
AppManager.TryResolve(out ITradeSettleBillGenerator generatorV2);
|
|
var checkDuplicateSet = new HashSet<string>();
|
|
//客户编号列表
|
|
foreach (var tradeContractGroup in tradeDic.Values)
|
|
{
|
|
var missingTradeCash = false;
|
|
|
|
if (tradeContractGroup.trade.TradeType != "结构化交易")
|
|
{
|
|
missingTradeCash = tradeContractGroup.trade_cash == null;
|
|
}
|
|
else if (tradeContractGroup.trade.IsGroup == 0)
|
|
{
|
|
missingTradeCash = tradeContractGroup.trade_cash == null || tradeContractGroup.trade.SubTrades.Any(O => O.trade_cash == null);
|
|
}
|
|
|
|
if (missingTradeCash)
|
|
{
|
|
resultList.Add(new TradeDocGenerateResult(tradeContractGroup.trade)
|
|
{
|
|
ErrorMessage = "缺少现金交割记录"
|
|
});
|
|
}
|
|
else if (generatorV2 != null)
|
|
{
|
|
var key = $"{tradeContractGroup.trade.id}_{tradeContractGroup.trade_cash.Action}_{tradeContractGroup.trade_cash.Notional}_{tradeContractGroup.trade_cash.UnwindNotional}";
|
|
if (!checkDuplicateSet.Add(key)) //判断重复
|
|
{
|
|
continue;
|
|
}
|
|
var result = GenerateSingleV2(generatorV2, tradeContractGroup, tradeContractGroup.trade_cash.id, docType);
|
|
if (PS.Config.Is方顿 && resultList.Any(x => x.OutputFilePath == result.OutputFilePath))
|
|
{
|
|
continue;
|
|
}
|
|
resultList.Add(result);
|
|
}
|
|
else
|
|
{
|
|
var result = GenerateSingleV1(tradeContractGroup, userId, userName, docType);
|
|
resultList.Add(result);
|
|
}
|
|
}
|
|
|
|
return resultList;
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
private TradeDocGenerateResult GenerateSingleV2(ITradeSettleBillGenerator generator, trade_contract_group tradeContractGroup, int tradeCashId, string docType = "DOCX")
|
|
{
|
|
try
|
|
{
|
|
var context = new SettlementBillGenerateContext(tradeCashId, tradeContractGroup.trade, ContractTypeEnum.Clearing, OptUser);
|
|
|
|
generator.Initialize(docType, context);
|
|
return generator.GenerateDocument();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
LogFactory.GetLogger("GenerateSingleV2").Error(ex);
|
|
|
|
return new TradeDocGenerateResult(tradeContractGroup.trade)
|
|
{
|
|
Exception = ex,
|
|
ErrorMessage = "出错:" + ex.Message
|
|
};
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
private TradeDocGenerateResult GenerateSingleV1(trade_contract_group contractGroup, int userId, string userName, string docType = "DOCX")
|
|
{
|
|
if (contractGroup == null)
|
|
{
|
|
throw new ArgumentNullException(nameof(contractGroup));
|
|
}
|
|
|
|
var contractBLL = new TradeContractBLL(this);
|
|
var dic = new Dictionary<string, object>();
|
|
var trade = contractGroup.trade;
|
|
var tradeCash = contractGroup.trade_cash;
|
|
var tradeContractR = contractGroup.ConfirmContractR;
|
|
if (tradeContractR == null)
|
|
{
|
|
throw new Exception(contractGroup.trade.TradeNumber + "该笔交易未生成交易确认书");
|
|
}
|
|
var needAddData = true;
|
|
|
|
#region 如果到期结算单已经生成过,则直接返回
|
|
var settlementDoc = contractBLL.GetContractDoc(trade.id, ContractTypeEnum.Clearing);
|
|
if (settlementDoc != null)
|
|
{
|
|
if (File.Exists(settlementDoc.AbsolutePath))
|
|
{
|
|
if (docType == "PDF")
|
|
{
|
|
var pdfPath = settlementDoc.AbsolutePath.Replace(".docx", ".pdf");
|
|
if (!File.Exists(pdfPath))
|
|
{
|
|
OfficeFileConverter.ConvertDocxToPDF(settlementDoc.AbsolutePath, pdfPath);
|
|
}
|
|
return new TradeDocGenerateResult(trade)
|
|
{
|
|
OutputFilePath = $"../App_Docs/GTJA/{settlementDoc.FileName.Replace(".docx", ".pdf")}"
|
|
};
|
|
}
|
|
|
|
return new TradeDocGenerateResult(trade)
|
|
{
|
|
OutputFilePath = $"../App_Docs/GTJA/{settlementDoc.FileName}"
|
|
};
|
|
}
|
|
else
|
|
{
|
|
needAddData = false;
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
var underlying = DataCacheProvider.GetUnderlyingDataSource().GetData(trade.UnderlyingCode);
|
|
if (underlying == null)
|
|
{
|
|
return new TradeDocGenerateResult(trade)
|
|
{
|
|
ErrorMessage = $"标的资产{trade.UnderlyingCode}信息未找到"
|
|
};
|
|
}
|
|
var client = DataCacheProvider.GetClientDataSource().GetData(trade.ClientId);
|
|
if (client == null)
|
|
{
|
|
return new TradeDocGenerateResult(trade)
|
|
{
|
|
ErrorMessage = $"客户(id:{trade.ClientId})信息未找到"
|
|
};
|
|
}
|
|
dic["{{客户名称}}"] = $"{trade.ClientName ?? ""}";
|
|
dic["{{交易方向}}"] = $"贵司{BuySellConvert.GetClientBuySell(contractGroup.trade.BuySell)}";
|
|
|
|
var tradeType = trade.TradeType == "香草期权" ? "普通" : (trade.TradeType == "结构化交易" ? trade.StructureType : trade.TradeType.Replace("期权", ""));
|
|
dic["{{期权类型}}"] = $"{trade.ExerciseModeCn}{tradeType}{trade.OptionType}期权";
|
|
dic["{{到期日}}"] = trade.ExerciseDate?.ToString("yyyy年M月d日");
|
|
dic["{{交易日}}"] = trade.TradeDate?.ToString("yyyy年M月d日");
|
|
dic["{{合约到期日}}"] = trade.MaturityDate?.ToString("yyyy年M月d日");
|
|
|
|
var variety = VarietyBLL.GetAllvarietyModel().FirstOrDefault(x => x.id == underlying.UnderlyingTypeId);
|
|
if (trade.TradeType == "合成价差期权")
|
|
{
|
|
dic["{{商品标的名称}}"] = synthetic_underlyingBLL.GetUnderlyingTipsInfo(trade.UnderlyingCode);
|
|
}
|
|
else
|
|
{
|
|
//合约代码和名称需要调整
|
|
var UnderlyingCode = underlying.UnderlyingCode;
|
|
if (Regex.IsMatch(UnderlyingCode, "^[a-zA-Z]+00"))
|
|
{
|
|
UnderlyingCode = UnderlyingCode.TrimEnd('0');
|
|
}
|
|
UnderlyingCode += "." + underlying.MarketCode;
|
|
dic["{{商品标的名称}}"] = PS.Config.Is东兴 ? UnderlyingCode : trade.UnderlyingCode;
|
|
}
|
|
|
|
var strUnit = variety.QuoteUnitSingle;
|
|
var tradeNotional = trade.Notional;
|
|
var tradeOriginalNotional = (trade.OriginalNotional ?? 0);
|
|
|
|
dic["{{商品标的数量}}"] = $"{tradeOriginalNotional.OtcFormatNotional()}{strUnit}";
|
|
dic["{{支付时间}}"] = "买方终止 / 到期时支付";
|
|
//期末价格
|
|
var endPrice = underlying.Price ?? 0;
|
|
//交割金额
|
|
double tradeCashAmount = 0;
|
|
double notional = 0;
|
|
if (tradeCash != null)
|
|
{
|
|
endPrice = tradeCash.FinalPrice ?? 0;
|
|
tradeCashAmount = tradeCash.Amount;
|
|
notional = tradeCash.Action == "系统操作-行权费" ? tradeCash.Notional : tradeCash.UnwindNotional ?? 0;
|
|
}
|
|
|
|
dic["{{执行价格}}"] = $"{(trade.ActualStrike ?? 0).OtcFormatUmPrice()}元/{strUnit}";
|
|
dic["{{期初价格}}"] = $"{(trade.SpotPrice ?? 0).OtcFormatUmPrice()}元/{strUnit}";
|
|
dic["{{期权价格}}"] = $"{(trade.TradeSinglePrice ?? 0).OtcFormatMoney(grouping: false)}元/{strUnit}";
|
|
dic["{{期权费率}}"] = $"{trade.PremiumRate?.OtcFormat(OtcFormatFlag.premiumRateP)}";
|
|
dic["{{期初名义本金}}"] = $"{(trade.OriginalStockEqvNotional ?? 0).OtcFormat(OtcFormatFlag.StockEqvNotional)}元";
|
|
dic["{{期末名义本金}}"] = $"{trade.StockEqvNotional.OtcFormat(OtcFormatFlag.StockEqvNotional)}元";
|
|
dic["{{期末价格}}"] = $"{endPrice.OtcFormatUmPrice()}元/{strUnit}";
|
|
dic["{{期权收益}}"] = $"{Math.Abs(tradeCashAmount / tradeNotional).OtcFormatFlex(2, 4)}元/{strUnit}";
|
|
dic["{{期末数量}}"] = $"{tradeNotional.OtcFormatNotional()}{strUnit}";
|
|
dic["{{期权费}}"] = $"{(trade.TradePrice ?? 0).OtcFormatMoney(grouping: false)}元";
|
|
dic["{{结算价}}"] = $"{Math.Abs(tradeCashAmount).OtcFormatMoney()}元";
|
|
dic["{{终止日}}"] = trade.UnWindDate?.ToString("yyyy年M月d日");
|
|
var req = new RunMarginCalculationReq(UserInfo)
|
|
{
|
|
tradeList = new List<trade> { trade },
|
|
settleDate = trade.UnWindDate.Value,
|
|
PriceProvider = new SinglePriceProvider(trade.UnderlyingCode, endPrice)
|
|
};
|
|
if (trade.IsGroup == 1)
|
|
{
|
|
req.tradeList = DbContext.trade.Where(x => x.ParentTradeId == trade.id).ToList();
|
|
}
|
|
var tradeSpans = MarginDefault.RunMarginCalculation(req);
|
|
if (tradeSpans?.Count > 0)
|
|
{
|
|
var margin = trade.IsGroup == 1 ? tradeSpans.Sum(x => x.WorstCastClientPayable ?? 0) : (tradeSpans[0].WorstCastClientPayable ?? 0);
|
|
dic["{{预付金}}"] = $"{Math.Abs(margin).OtcFormatMoney(grouping: false)}元";
|
|
}
|
|
else
|
|
{
|
|
dic["{{预付金}}"] = "0元";
|
|
}
|
|
dic["{{结算价格}}"] = dic["{{期权收益}}"];
|
|
|
|
var isGJBuyer = trade.BuySell == "买入";
|
|
double incomes;
|
|
if (isGJBuyer)
|
|
{
|
|
incomes = tradeCashAmount - (notional * trade.TradeSinglePrice) ?? 0;
|
|
}
|
|
else
|
|
{
|
|
incomes = tradeCashAmount + (notional * trade.TradeSinglePrice) ?? 0;
|
|
}
|
|
dic["{{结算净额}}"] = $"{Math.Abs(incomes).OtcFormatMoney(grouping: false)}元";
|
|
dic["{{结算方式}}"] = incomes > 0 ? "贵司向我司支付结算净额" : "我司向贵司支付结算净额";
|
|
dic["{{到期盈亏}}"] = $"{Math.Abs(incomes).OtcFormatMoney(grouping: false)}元";
|
|
|
|
//东兴结算净额处理逻辑(卖价差期权)
|
|
dic["{{客户结算净额}}"] = $"{(Math.Abs(tradeCashAmount) - (notional * trade.TradeSinglePrice))?.OtcFormatMoney(grouping: false)}元"; ;
|
|
dic["{{机构结算净额}}"] = $"{((notional * trade.TradeSinglePrice) - Math.Abs(tradeCashAmount))?.OtcFormatMoney(grouping: false)}元"; ;
|
|
|
|
//合同编号
|
|
string contractNo;
|
|
string outPutFileName;
|
|
if (settlementDoc != null)
|
|
{
|
|
contractNo = settlementDoc.Code;
|
|
outPutFileName = settlementDoc.FileName;
|
|
}
|
|
else
|
|
{
|
|
var contractIndex = contractBLL.GetContractNo("GTJASettlement");
|
|
if (PS.Config.CompanyID == "中财资本")
|
|
{
|
|
contractNo = $"{trade.TradeNumber}S";
|
|
}
|
|
else
|
|
{
|
|
contractNo = $"{client.Number}C{contractIndex}S";
|
|
}
|
|
outPutFileName = $"{client.Name}到期结算单C{contractIndex}S.docx";
|
|
}
|
|
dic["{{合同编号}}"] = contractNo;
|
|
dic["{{合同时间}}"] = $"{DateTime.Now:yyyy年M月d日}";
|
|
dic["{{确认书编号}}"] = tradeContractR.ContractCode;
|
|
|
|
try
|
|
{
|
|
|
|
var templateDir = OtcAppContext.MapPath("~/App_Docs/GTJA");
|
|
var templatePath = OtcAppContext.MapPath("~/App_Docs/导出模板/到期结算单模板.docx");
|
|
if (trade.IsUsePremiumRate != null && trade.IsUsePremiumRate.Value)
|
|
{
|
|
templatePath = OtcAppContext.MapPath("~/App_Docs/导出模板/到期结算单(名义本金)模板.docx");
|
|
}
|
|
|
|
var outPutFilePath = Path.Combine(templateDir, outPutFileName);
|
|
|
|
MsWordTempalteHelper.GenerateFromTemplate(templatePath, dic, outPutFilePath);
|
|
|
|
if (docType == "PDF" && !outPutFilePath.EndsWith(".pdf", StringComparison.OrdinalIgnoreCase))
|
|
{
|
|
MsWordFormatConverter.ConvertToPDF(outPutFilePath, outPutFilePath.Replace(".docx", ".pdf"));
|
|
}
|
|
|
|
//更新操作时间
|
|
var now = DateTime.Now;
|
|
File.SetLastAccessTime(outPutFilePath, now);
|
|
|
|
#region --- Add trade_contract_document and trade_contract_r records
|
|
|
|
if (needAddData)
|
|
{
|
|
var nowDate = DateTime.Now;
|
|
var contractRecord = new trade_contract_document();
|
|
DbContext.trade_contract_document.Add(contractRecord);
|
|
contractRecord.Code = settlementDoc != null ? settlementDoc.Code : dic["{{合同编号}}"].ToString();
|
|
contractRecord.ValueDate = valuedateBLL.ValueDate;
|
|
contractRecord.BuyerId = isGJBuyer ? 0 : trade.ClientId;
|
|
contractRecord.BuyerName = isGJBuyer ? PS.Config.CompanyFullName : trade.ClientName;
|
|
contractRecord.SellerId = isGJBuyer ? trade.ClientId : 0;
|
|
contractRecord.SellerName = isGJBuyer ? trade.ClientName : PS.Config.CompanyFullName;
|
|
contractRecord.FileType = FileTypeEnum.Word;
|
|
contractRecord.Status = ContractStatusEnum.Draft;
|
|
contractRecord.Paths = $"App_Docs\\GTJA\\{outPutFileName}";
|
|
contractRecord.FileName = outPutFileName;
|
|
contractRecord.Type = ContractTypeEnum.Clearing;
|
|
contractRecord.OptId = userId;
|
|
contractRecord.OptName = userName;
|
|
contractRecord.OptDate = nowDate;
|
|
|
|
var contractTradeRelation = new trade_contract_r();
|
|
DbContext.trade_contract_r.Add(contractTradeRelation);
|
|
contractTradeRelation.TradeId = trade.id;
|
|
contractTradeRelation.TradeNumber = trade.TradeNumber;
|
|
contractTradeRelation.ContractCode = contractRecord.Code;
|
|
contractTradeRelation.TradeClearCode = contractRecord.Code;
|
|
contractTradeRelation.Type = ContractTypeEnum.Clearing;
|
|
contractTradeRelation.OptId = userId;
|
|
contractTradeRelation.OptName = userName;
|
|
contractTradeRelation.OptDate = nowDate;
|
|
contractTradeRelation.TradeCashId = tradeCash.id;
|
|
contractTradeRelation.IsValid = true;
|
|
|
|
DbContext.SaveChanges();
|
|
}
|
|
|
|
#endregion --- Add trade_contract_document and trade_contract_r records
|
|
|
|
return new TradeDocGenerateResult(trade)
|
|
{
|
|
OutputFilePath = $"/App_Docs/GTJA/{(docType == "PDF" ? outPutFileName.Replace(".docx", ".pdf") : outPutFileName)}"
|
|
};
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
LogFactory.GetLogger<SettlementBillGenerateService>().Error("GenerateSingleSettleBill出错", ex);
|
|
return new TradeDocGenerateResult(trade)
|
|
{
|
|
ErrorMessage = "出错:" + ex.Message
|
|
};
|
|
}
|
|
}
|
|
}
|
|
}
|