550 lines
24 KiB
C#
550 lines
24 KiB
C#
using YLErp.BLL;
|
||
using YLErp.DBModels.Consts;
|
||
using YLErp.Model;
|
||
using YLErp.Models;
|
||
using YLErp.Modules.ClientModule;
|
||
using YLErp.Modules.TradeDalModule;
|
||
using YLErp.MsOffice;
|
||
using YLErp.Office.Converters;
|
||
using YLErp.Plugins.TradeDocGenerator.Abstracts;
|
||
|
||
namespace YLErp.Modules.TradeModule.DocGenerateModule
|
||
{
|
||
/// <summary>
|
||
/// 生成交易确认书
|
||
/// </summary>
|
||
public class BatchConfirmationGenerateService : YLBaseService
|
||
{
|
||
public BatchConfirmationGenerateService(OptUserInfo userInfo) : base(userInfo)
|
||
{
|
||
}
|
||
|
||
public BatchConfirmationGenerateService(YLBaseService baseService) : base(baseService)
|
||
{
|
||
}
|
||
|
||
/// <summary>
|
||
/// 生成交易确认书
|
||
/// </summary>
|
||
public IEnumerable<TradeDocGenerateResult> Generate(IEnumerable<int> tradeIds, string docType, DateTime? startDate = null, DateTime? endDate = null)
|
||
{
|
||
if (tradeIds == null)
|
||
{
|
||
throw new ArgumentNullException(nameof(tradeIds));
|
||
}
|
||
|
||
if (docType == null)
|
||
{
|
||
throw new ArgumentNullException(nameof(docType));
|
||
}
|
||
|
||
//----------------------------------
|
||
// 获取当日行权 平仓 到期的有效交易
|
||
//----------------------------------
|
||
var statusList = new List<string>() {
|
||
ConsTrade.确认成交
|
||
};
|
||
if (GlobalConfig.EnableGenerateOnTradeClosed)
|
||
{
|
||
statusList.Add(ConsTrade.已到期);
|
||
statusList.Add(ConsTrade.已平仓);
|
||
statusList.Add(ConsTrade.已执行);
|
||
statusList.Add(ConsTrade.审批中);
|
||
}
|
||
var service = new TradeDalService(this);
|
||
//var tradeQuery = service
|
||
// .GetTradeOrEodTrade(tradeIds, ValueDate, true)
|
||
// .Where(O =>
|
||
// statusList.Contains(O.TradeStatus)
|
||
// && (O.ParentTradeId == null || O.ParentTradeId < 1)
|
||
// && O.ClientId != null);
|
||
|
||
//var tradeQuery = from trad in DbContext.trade
|
||
// where tradeIds.Contains(trad.id)
|
||
// && statusList.Contains(trad.TradeStatus)
|
||
// && trad.ValidState != "InValid" && trad.ClientId != null
|
||
// && (trad.ParentTradeId == null || trad.ParentTradeId < 1)
|
||
// select trad;
|
||
|
||
//----------------------------------
|
||
// 交易现金交割记录
|
||
//----------------------------------
|
||
List<trade> allTrades = DbContext.trade.Where(x => tradeIds.Contains(x.id)).ToList();
|
||
if (allTrades.Count < 1)
|
||
{
|
||
throw new ServiceException("没有已确认的记录信息!");
|
||
}
|
||
var tradeDic = allTrades.Where(O =>
|
||
statusList.Contains(O.TradeStatus)
|
||
&& O.ClientId != 0
|
||
&& O.ParentTradeId == 0)
|
||
.ToDictionary(n => n.id, n => new trade_contract_group { trade = n });
|
||
tradeIds = allTrades.Select(O => O.id);
|
||
|
||
//----------------------------------
|
||
// 生成交易确认书
|
||
//----------------------------------
|
||
|
||
var resultList = new List<TradeDocGenerateResult>();
|
||
|
||
AppManager.TryResolve(out ITradeConfirmationGenerator generatorV2);
|
||
|
||
var tradeContractGroupTradeIds = tradeDic.Values.Select(x => x.trade.id).ToList();
|
||
|
||
// 如果包含互换交易,强制走V1默认逻辑(不走插件)
|
||
var hasSwapTrade = tradeDic.Values.Any(x => x.trade.TradeType == "收益互换");
|
||
|
||
if (generatorV2 != null && hasSwapTrade)
|
||
{
|
||
var result = GenerateSingleV2(
|
||
generatorV2,
|
||
tradeDic.Values.Select(O => O.trade).ToList(),
|
||
tradeDic.Values.Select(O => (O.trade.trade_cash?.id) ?? 0).ToList(),
|
||
docType,
|
||
startDate,
|
||
endDate);
|
||
|
||
resultList.Add(result);
|
||
}
|
||
else
|
||
{
|
||
foreach (var item in tradeDic)
|
||
{
|
||
resultList.Add(GenerateSingleV1(item.Value, docType));
|
||
}
|
||
}
|
||
if (generatorV2 == null || hasSwapTrade)
|
||
{
|
||
DbContext.SaveChanges();
|
||
}
|
||
|
||
return resultList;
|
||
}
|
||
|
||
/// <summary>
|
||
///
|
||
/// </summary>
|
||
private TradeDocGenerateResult GenerateSingleV2(ITradeConfirmationGenerator generator, List<trade> trades, List<int> tradeCashIds, string docType = "DOCX", DateTime? startDate = null, DateTime? endDate = null)
|
||
{
|
||
try
|
||
{
|
||
var context = new ConfirmationGenerateContext(tradeCashIds, trades, ContractTypeEnum.Trade, OptUser, startDate, endDate);
|
||
generator.Initialize(docType, context);
|
||
return generator.GenerateDocument();
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
LogFactory.GetLogger("GenerateSingleV2").Error(ex);
|
||
|
||
return new TradeDocGenerateResult(trades)
|
||
{
|
||
ErrorMessage = ex.Message
|
||
};
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
///
|
||
/// </summary>
|
||
private TradeDocGenerateResult GenerateSingleV1(trade_contract_group contractGroup, string docType = "DOCX")
|
||
{
|
||
var logger = LogFactory.GetLogger("生成确认书详细日志");
|
||
logger.Info($"[BatchGenerateSingleV1] 开始处理 - docType: {docType}");
|
||
|
||
if (contractGroup == null)
|
||
{
|
||
logger.Error("[BatchGenerateSingleV1] contractGroup 为 null");
|
||
throw new ArgumentNullException(nameof(contractGroup));
|
||
}
|
||
|
||
var trade = contractGroup.trade;
|
||
logger.Info($"[BatchGenerateSingleV1] 交易信息 - TradeId: {trade?.id}, TradeNumber: {trade?.TradeNumber}, TradeType: {trade?.TradeType}");
|
||
|
||
var contractBLL = new TradeContractBLL(this);
|
||
tradeBLL.SetFieldsByTradeType(trade);
|
||
var needAddData = true;
|
||
|
||
#region 如果之前交易确认书已经生成过,则直接返回
|
||
|
||
var confirmDoc = contractBLL.GetContractDoc(trade.id, ContractTypeEnum.Trade);
|
||
if (confirmDoc != null)
|
||
{
|
||
if (File.Exists(confirmDoc.AbsolutePath))
|
||
{
|
||
if (docType == "PDF")
|
||
{
|
||
var pdfPath = confirmDoc.AbsolutePath.Replace(".docx", ".pdf");
|
||
if (!File.Exists(pdfPath))
|
||
{
|
||
OfficeFileConverter.ConvertDocxToPDF(confirmDoc.AbsolutePath, pdfPath);
|
||
}
|
||
|
||
return new TradeDocGenerateResult(trade)
|
||
{
|
||
//OutputFilePath = $"/App_Docs/GTJA/{confirmDoc.FileName.Replace(".doc", ".pdf")}"
|
||
OutputFilePath = YLErp.Helpers.PathHelper.PhysicalPathToWebPath(pdfPath, OtcAppContext.RootPath)
|
||
};
|
||
}
|
||
|
||
return new TradeDocGenerateResult(trade)
|
||
{
|
||
//OutputFilePath = $"/App_Docs/GTJA/{confirmDoc.FileName}"
|
||
OutputFilePath = YLErp.Helpers.PathHelper.PhysicalPathToWebPath(confirmDoc.AbsolutePath, OtcAppContext.RootPath)
|
||
};
|
||
}
|
||
else
|
||
{
|
||
needAddData = false;
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
var isGJBuyer = trade.BuySell == "买入";
|
||
|
||
var underlying = underlying_managerBLL.GetByCode(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 = $"客户{trade.ClientId}信息未找到"
|
||
};
|
||
}
|
||
|
||
var dic = new Dictionary<string, object>
|
||
{
|
||
["{{乙方名称}}"] = client.Name
|
||
};
|
||
|
||
if (isGJBuyer)
|
||
{
|
||
dic["{{甲方方向}}"] = "买方";
|
||
dic["{{乙方方向}}"] = "卖方";
|
||
}
|
||
else
|
||
{
|
||
dic["{{甲方方向}}"] = "卖方";
|
||
dic["{{乙方方向}}"] = "买方";
|
||
}
|
||
|
||
|
||
dic["{{交易日}}"] = trade.TradeDate?.ToString("yyyy年M月d日");
|
||
if (trade.TradeType == "香草期权" || trade.TradeType == "亚式期权")
|
||
{
|
||
dic["{{生效日}}"] = trade.TradeDate?.ToString("yyyy年M月d日");
|
||
}
|
||
else
|
||
{
|
||
dic["{{生效日}}"] = trade.StartDate?.ToString("yyyy年M月d日");
|
||
}
|
||
if (trade.TradeType == "亚式期权")
|
||
{
|
||
dic["{{均价起算日}}"] = trade.trade_asian_option.AveragingPeriodStartDate?.ToString("yyyy年M月d日");
|
||
dic["{{奇异结构}}"] = $"{trade.trade_asian_option.StrikeTypeCn}的{trade.trade_asian_option.PayoffTypeCn}亚式";
|
||
}
|
||
dic["{{到期日}}"] = trade.ExerciseDate?.ToString("yyyy年M月d日");
|
||
dic["{{行权日}}"] = "到期日";
|
||
|
||
dic["{{自动行权}}"] = "到期实值自动行权";
|
||
|
||
//商品标的
|
||
|
||
if (trade.TradeType == "合成价差期权")
|
||
{
|
||
dic["{{商品标的名称}}"] = synthetic_underlyingBLL.GetUnderlyingTipsInfo(trade.UnderlyingCode);
|
||
}
|
||
else
|
||
{
|
||
dic["{{商品标的名称}}"] = trade.UnderlyingCode;
|
||
}
|
||
|
||
var strUnit = underlying.TradeUnitString;
|
||
var notional = trade.Notional;
|
||
|
||
dic["{{报价单位}}"] = strUnit;
|
||
dic["{{商品标的数量}}"] = $"{notional}{strUnit}";
|
||
dic["{{商品标的交易所}}"] = underlying.MarketName;
|
||
|
||
//价格
|
||
if (trade.ActualStrike != null)
|
||
{
|
||
if (trade.IsMoneynessOption == "是")
|
||
{
|
||
dic["{{执行价格}}"] = (trade.Strike ?? 0).OtcFormatUmPrice(true);
|
||
}
|
||
else
|
||
{
|
||
dic["{{执行价格}}"] = $"{trade.ActualStrike?.OtcFormatUmPrice()}元/{strUnit}";
|
||
}
|
||
}
|
||
else
|
||
{
|
||
dic["{{执行价格}}"] = "不适用";
|
||
}
|
||
|
||
var tradeType = trade.TradeType == "香草期权" ? "普通" : (trade.TradeType == "结构化交易" ? trade.StructureType : trade.TradeType.Replace("期权", ""));
|
||
dic["{{期权类型}}"] = $"{trade.ExerciseModeCn}{tradeType}{trade.OptionType}期权";
|
||
|
||
dic["{{期权费}}"] = $"{(trade.TradePrice ?? 0).OtcFormatMoney(grouping: false)}元";
|
||
dic["{{协议编号}}"] = client.Remark;
|
||
|
||
dic["{{期权价格}}"] = $"{(trade.TradeSinglePrice ?? 0).OtcFormat(OtcFormatFlag.tradeSinglePrice)}元/{strUnit}";
|
||
dic["{{支付时间}}"] = trade.PremiumPayDate != null ? "提前终止/到期时支付" : "已支付";
|
||
|
||
dic["{{期权方向}}"] = $"甲方{trade.BuySell}";
|
||
dic["{{名义本金}}"] = trade.StockEqvNotional.OtcFormat(OtcFormatFlag.StockEqvNotional);
|
||
dic["{{期初价格}}"] = (trade.SpotPrice ?? 0).OtcFormatUmPrice();
|
||
dic["{{期权费率}}"] = ((trade.PremiumRate ?? ((trade.TradePrice ?? 0) / trade.OriginalStockEqvNotional.Value)) * 100).OtcFormatFlex(2);
|
||
|
||
var settlementType = "价格";
|
||
if (trade.SettlementType == SettlementTypeEnum.SettlePrice)
|
||
{
|
||
settlementType = "结算价";
|
||
}
|
||
else if (trade.SettlementType == SettlementTypeEnum.ClosePrice)
|
||
{
|
||
settlementType = "收盘价";
|
||
}
|
||
|
||
if (trade.ExerciseMode == "American")
|
||
{
|
||
dic["{{美式期权结算价}}"] = $"所属交易所公布的标的合约可成交的最新价";
|
||
dic["{{欧式期权结算价}}"] = $"美式期权不适用";
|
||
}
|
||
else
|
||
{
|
||
dic["{{美式期权结算价}}"] = $"欧式期权不适用";
|
||
dic["{{欧式期权结算价}}"] = $"所属交易所在到期日收盘后公布的标的合约{settlementType}";
|
||
}
|
||
|
||
if (trade.UnderlyingInstrumentType != "CommodityFutures")
|
||
{
|
||
dic["{{证券名称}}"] = underlying.UnderlyingName;
|
||
dic["{{证券代码}}"] = underlying.UnderlyingCode;
|
||
|
||
dic["{{账户信息乙方}}"] = client.Name;
|
||
dic["{{联系方式乙方}}"] = client.Name;
|
||
dic["{{联系方式乙方联系人}}"] = client.Name;
|
||
dic["{{联系方式乙方电话}}"] = client.Phone;
|
||
dic["{{联系方式乙方电子邮件}}"] = client.Email;
|
||
|
||
var bankcard = ClientDataQueryService.GetBankCard(trade.ClientId);
|
||
if (bankcard != null)
|
||
{
|
||
dic["{{账户信息乙方户名}}"] = bankcard.ClientName;
|
||
dic["{{账户信息乙方账号}}"] = bankcard.Card;
|
||
dic["{{账户信息乙方开户行}}"] = bankcard.Bank;
|
||
}
|
||
|
||
dic["{{期权方向}}"] = $"甲方{trade.BuySell}";
|
||
dic["{{名义本金}}"] = trade.StockEqvNotional.OtcFormat(OtcFormatFlag.StockEqvNotional);
|
||
}
|
||
|
||
if (trade.OptionType == "看涨")
|
||
{
|
||
if (trade.ExerciseMode == "American")
|
||
{
|
||
dic["{{美式期权结算金额}}"] =
|
||
$"(行权时{trade.UnderlyingCode}合约可成交最新价 - {trade.ActualStrike.OtcFormatUmPrice()})× {notional.OtcFormatNotional()}";
|
||
dic["{{欧式期权结算金额}}"] = $"美式期权不适用";
|
||
}
|
||
else
|
||
{
|
||
dic["{{美式期权结算金额}}"] = $"欧式期权不适用";
|
||
dic["{{欧式期权结算金额}}"] =
|
||
$"({trade.ExerciseDate?.ToString("yyyy年M月d日")}{trade.UnderlyingCode}合约{settlementType} - {trade.ActualStrike.OtcFormatUmPrice()})× {notional.OtcFormatNotional()}";
|
||
}
|
||
}
|
||
else if (trade.OptionType == "看跌")
|
||
{
|
||
if (trade.ExerciseMode == "American")
|
||
{
|
||
dic["{{美式期权结算金额}}"] =
|
||
$"({trade.ActualStrike.OtcFormatUmPrice()} - 行权时{trade.UnderlyingCode}合约可成交最新价)× {notional.OtcFormatNotional()}";
|
||
dic["{{欧式期权结算金额}}"] = $"美式期权不适用";
|
||
}
|
||
else
|
||
{
|
||
dic["{{美式期权结算金额}}"] = $"欧式期权不适用";
|
||
dic["{{欧式期权结算金额}}"] =
|
||
$"({trade.ActualStrike.OtcFormatUmPrice()} - {trade.ExerciseDate?.ToString("yyyy年M月d日")}{trade.UnderlyingCode}合约{settlementType})× {notional.OtcFormatNotional()}";
|
||
}
|
||
}
|
||
|
||
//合同编号
|
||
string contractNo;
|
||
string outPutFileName;
|
||
if (confirmDoc != null)
|
||
{
|
||
contractNo = confirmDoc.Code;
|
||
outPutFileName = confirmDoc.FileName;
|
||
}
|
||
else
|
||
{
|
||
var contractIndex = contractBLL.GetContractNo("GTJA");
|
||
if (PS.Config.CompanyID == "中财资本")
|
||
{
|
||
contractNo = $"{trade.TradeNumber}";
|
||
}
|
||
else
|
||
{
|
||
contractNo = $"{client.Number}C{contractIndex}";
|
||
}
|
||
outPutFileName = $"{client.Name}交易确认书C{contractIndex}.docx";
|
||
}
|
||
dic["{{合同编号}}"] = contractNo;
|
||
dic["{{结算方式}}"] = "人民币现金结算";
|
||
dic["{{补充}}"] = "补充";
|
||
|
||
var batchLogger = LogFactory.GetLogger("生成确认书详细日志");
|
||
try
|
||
{
|
||
batchLogger.Info($"[BatchGenerateSingleV1] 开始生成文档 - TradeId: {trade?.id}");
|
||
batchLogger.Info($"[BatchGenerateSingleV1] 模板类型: {trade.TradeType}, IsUsePremiumRate: {trade.IsUsePremiumRate}");
|
||
|
||
var templateDir = OtcAppContext.MapPath("~/App_Docs/GTJA");
|
||
batchLogger.Info($"[BatchGenerateSingleV1] templateDir: {templateDir}");
|
||
|
||
var templatePath = OtcAppContext.MapPath("~/App_Docs/导出模板/交易确认书模板.docx");
|
||
if (trade.TradeType == "亚式期权")
|
||
{
|
||
templatePath = OtcAppContext.MapPath("~/App_Docs/导出模板/交易确认书(亚式期权)模板.docx");
|
||
batchLogger.Info($"[BatchGenerateSingleV1] 使用亚式期权模板");
|
||
}
|
||
|
||
if (trade.IsUsePremiumRate != null && trade.IsUsePremiumRate.Value)
|
||
{
|
||
templatePath = OtcAppContext.MapPath("~/App_Docs/导出模板/交易确认书(名义本金)模板.docx");
|
||
batchLogger.Info($"[BatchGenerateSingleV1] 使用名义本金模板");
|
||
}
|
||
|
||
batchLogger.Info($"[BatchGenerateSingleV1] 最终模板路径: {templatePath}");
|
||
batchLogger.Info($"[BatchGenerateSingleV1] 输出文件名: {outPutFileName}");
|
||
|
||
// 检查模板文件是否存在
|
||
if (!File.Exists(templatePath))
|
||
{
|
||
batchLogger.Error($"[BatchGenerateSingleV1] 模板文件不存在: {templatePath}");
|
||
return new TradeDocGenerateResult(trade) { ErrorMessage = $"模板文件不存在: {templatePath}" };
|
||
}
|
||
batchLogger.Info($"[BatchGenerateSingleV1] 模板文件存在,准备生成");
|
||
|
||
LogFactory.GetLogger("交易确认书").Info("交易确认书:" + outPutFileName);
|
||
|
||
var outPutFilePath = Path.Combine(templateDir, outPutFileName);
|
||
batchLogger.Info($"[BatchGenerateSingleV1] 输出文件路径: {outPutFilePath}");
|
||
|
||
// 确保输出目录存在
|
||
if (!Directory.Exists(templateDir))
|
||
{
|
||
batchLogger.Info($"[BatchGenerateSingleV1] 创建输出目录: {templateDir}");
|
||
Directory.CreateDirectory(templateDir);
|
||
}
|
||
|
||
// --- 添加详细诊断日志 ---
|
||
batchLogger.Info($"[BatchGenerateSingleV1] 诊断信息 - dic 键数量: {dic?.Count ?? 0}");
|
||
if (dic != null)
|
||
{
|
||
foreach (var key in dic.Keys.Take(10))
|
||
{
|
||
var value = dic[key];
|
||
batchLogger.Info($"[BatchGenerateSingleV1] 模板变量 - {key}: {(value == null ? "null" : value.GetType().Name)} = {value}");
|
||
}
|
||
}
|
||
batchLogger.Info($"[BatchGenerateSingleV1] 诊断信息 - templatePath: {templatePath}");
|
||
batchLogger.Info($"[BatchGenerateSingleV1] 诊断信息 - outPutFilePath: {outPutFilePath}");
|
||
batchLogger.Info($"[BatchGenerateSingleV1] 诊断信息 - MsWordTempalteHelper 类型: {typeof(MsWordTempalteHelper).FullName}");
|
||
batchLogger.Info($"[BatchGenerateSingleV1] 诊断信息 - MsWordTempalteHelper 程序集: {typeof(MsWordTempalteHelper).Assembly?.FullName}");
|
||
// --- 诊断日志结束 ---
|
||
|
||
batchLogger.Info($"[BatchGenerateSingleV1] 调用 MsWordTempalteHelper.GenerateFromTemplate");
|
||
MsWordTempalteHelper.GenerateFromTemplate(templatePath, dic, outPutFilePath);
|
||
batchLogger.Info($"[BatchGenerateSingleV1] MsWordTempalteHelper.GenerateFromTemplate 完成");
|
||
|
||
if (docType == "PDF" && !outPutFilePath.EndsWith(".pdf", StringComparison.OrdinalIgnoreCase))
|
||
{
|
||
OfficeFileConverter.ConvertDocxToPDF(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)
|
||
{
|
||
contractBLL.DeleteConfirmBook(trade.id, null);
|
||
|
||
var nowDate = DateTime.Now;
|
||
|
||
var contractRecord = new trade_contract_document();
|
||
DbContext.trade_contract_document.Add(contractRecord);
|
||
contractRecord.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.Trade;
|
||
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.Type = ContractTypeEnum.Trade;
|
||
contractTradeRelation.OptId = UserId;
|
||
contractTradeRelation.OptName = UserName;
|
||
contractTradeRelation.OptDate = nowDate;
|
||
contractTradeRelation.TradeCashId = contractGroup.trade_cash == null ? 0 : contractGroup.trade_cash.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 e)
|
||
{
|
||
batchLogger.Error($"[BatchGenerateSingleV1] 发生异常 - TradeId: {trade?.id}, TradeNumber: {trade?.TradeNumber}", e);
|
||
batchLogger.Error($"[BatchGenerateSingleV1] 异常类型: {e.GetType().FullName}");
|
||
batchLogger.Error($"[BatchGenerateSingleV1] 异常消息: {e.Message}");
|
||
batchLogger.Error($"[BatchGenerateSingleV1] 异常堆栈: {e.StackTrace}");
|
||
|
||
if (e.InnerException != null)
|
||
{
|
||
batchLogger.Error($"[BatchGenerateSingleV1] 内部异常类型: {e.InnerException.GetType().FullName}");
|
||
batchLogger.Error($"[BatchGenerateSingleV1] 内部异常消息: {e.InnerException.Message}");
|
||
batchLogger.Error($"[BatchGenerateSingleV1] 内部异常堆栈: {e.InnerException.StackTrace}");
|
||
}
|
||
|
||
LogFactory.GetLogger<ConfirmationGenerateService>().Error("GenerateSingleConfirmBook出错", e);
|
||
return new TradeDocGenerateResult(trade) { ErrorMessage = e.Message };
|
||
}
|
||
}
|
||
}
|
||
}
|