using NPOI.Util; using Org.BouncyCastle.Asn1.Ocsp; using System.Text; using YLErp.BLL; using YLErp.BLL.GenerateDocument; using YLErp.DBModels.Consts; using YLErp.Helpers; using YLErp.Model; using YLErp.Model.Enum; using YLErp.Models; using YLErp.Modules.TradeDalModule; using YLErp.MsOffice; using YLErp.Modules.TradeModule.DealModule; using YLErp.Office; using YLErp.Office.Converters; using YLErp.Plugins.TradeDocGenerator.Abstracts; namespace YLErp.Modules.TradeModule.DocGenerateModule { /// /// 生成交易确认书 /// public class ConfirmationGenerateService : YLBaseService { public ConfirmationGenerateService(OptUserInfo userInfo) : base(userInfo) { } public ConfirmationGenerateService(YLBaseService baseService) : base(baseService) { } /// /// 生成交易确认书 /// public List Generate(IEnumerable tradeIds, string docType) { var logger = LogFactory.GetLogger("生成确认书详细日志"); logger.Info($"[Generate] 开始生成确认书 - tradeIds: {string.Join(",", tradeIds)}, docType: {docType}"); if (tradeIds == null) { logger.Error("[Generate] tradeIds 为 null"); throw new ArgumentNullException(nameof(tradeIds)); } if (docType == null) { logger.Error("[Generate] docType 为 null"); throw new ArgumentNullException(nameof(docType)); } //---------------------------------- // 获取当日行权 平仓 到期的有效交易 //---------------------------------- List statusList = new List() { ConsTrade.确认成交 }; if (GlobalConfig.EnableGenerateOnTradeClosed) { statusList.Add(ConsTrade.已到期); statusList.Add(ConsTrade.已平仓); statusList.Add(ConsTrade.已执行); statusList.Add(ConsTrade.审批中); } TradeDalService service = new TradeDalService(this); //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; //---------------------------------- // 交易现金交割记录 //---------------------------------- logger.Info("[Generate] 开始查询交易数据"); List allTradeList = allTradeList = DbContext.trade.Where(x => tradeIds.Contains(x.id)).ToList(); logger.Info($"[Generate] 查询到交易数: {allTradeList.Count}"); if (allTradeList.Count < 1) { logger.Error("[Generate] 没有找到交易记录"); throw new ServiceException("没有已确认的记录信息!"); } var tradeDic = allTradeList.Where(O => statusList.Contains(O.TradeStatus) && O.ClientId != 0 && O.ParentTradeId == 0) .ToDictionary(n => n.id, n => new trade_contract_group { trade = n }); var cashQuery = from trade in allTradeList join tradeCash in DbContext.trade_cash on trade.id equals tradeCash.TradeId where tradeCash.ValidState != ConsGlobal.InValid && !tradeCash.IsDeleted && tradeCash.Action == ClientCashInCashOut.系统操作_期权费 select tradeCash; var cashDatas = cashQuery.ToDictionary(K => K.TradeId, V => V); //var cashSwapQuery = from trade in allTradeList // join tradeCashSwap in DbContext.swap_event on trade.id equals tradeCashSwap.SwapTradeId // where tradeCashSwap.EventType == 9 // select tradeCashSwap; //var cashSwapDatas = cashSwapQuery.ToDictionary(K => K.SwapTradeId, V => V); trade_cash cash = null; //swap_event cashSwap = null; foreach (var item in tradeDic.Values) { if (item.trade.TradeType == "结构化交易") { item.trade.SubTrades = allTradeList.Where(O => O.ParentTradeId == item.trade.id); List cashTig = new List(); foreach (var t in item.trade.SubTrades) { if (cashDatas.TryGetValue(t.id, out cash)) { t.trade_cash = cash; item.trade.trade_cash = cash; } } if (item.trade.IsGroup == 1) { item.trade.SubTrades = DbContext.trade.Where(O => O.ParentTradeId == item.trade.id).ToList(); foreach (var t in item.trade.SubTrades) { t.trade_cash = DbContext.trade_cash.FirstOrDefault(l => l.TradeId == t.id); } if (cashDatas.TryGetValue(item.trade.id, out cash)) { item.trade.trade_cash = cash; } } } else { if (item.trade.TradeType == "累计期权") { new OptionTradeActionRestoreService(this).RestoreTradeDataToSpecialDay(item.trade, item.trade.TradeDate.Value); } if (cashDatas.TryGetValue(item.trade.id, out cash)) { item.trade_cash = cash; item.trade.trade_cash = cash; } } } //---------------------------------- // 生成交易确认书 //---------------------------------- var resultList = new List(); AppManager.TryResolve(out ITradeConfirmationGenerator generatorV2); if (generatorV2 == null && !PS.Config.UseOldGenerateBook) { var baseGenerate = BatchGenerateFactory.GetInstance(tradeIds, UserId, UserName, ContractTypeEnum.Trade, docType); var returnInfo = baseGenerate.GenerateBooks(); var trad = new trade(); resultList = returnInfo.Content.Select(n => new TradeDocGenerateResult(trad) { OutputFilePath = n }).ToList(); if (!returnInfo.Success) { resultList.Add(new TradeDocGenerateResult(trad) { ErrorMessage = returnInfo.Msg }); } return resultList; } var tradeContractGroupTradeIds = tradeDic.Values.Select(x => x.trade.id).ToList(); //var childs = DbContext.trade.Where(x => tradeContractGroupTradeIds.Contains(x.ParentTradeId ?? 0)); var childs = service.GetStructTradeFromTradeOrEodTrade(tradeContractGroupTradeIds, SystemValueDate, true); LogFactory.GetLogger("交易确认书").Info("交易确认书1:" + string.Join(",", tradeContractGroupTradeIds)); if (PS.Config.Company == Configuration.CompanyEnum.浙商) { LogFactory.GetLogger("交易确认书").Info("交易确认书浙商"); if (generatorV2 != null) { LogFactory.GetLogger("交易确认书").Info("交易确认书插件"); var result = GenerateSingleV2(generatorV2, null, docType , allTradeList); resultList.Add(result); } } else { foreach (var tradeContractGroup in tradeDic.Values) { //判断是否为期权交易(非收益互换的交易强制走默认逻辑V1,不走插件) var isOptionTrade = tradeContractGroup.trade.TradeType != "收益互换"; //插件版本(期权交易强制使用V1默认逻辑) if ((tradeContractGroup.trade.TradeType != "结构化交易" && tradeContractGroup.trade.TradeType != "收益互换" && tradeContractGroup.trade_cash == null) || (tradeContractGroup.trade.TradeType == "结构化交易" && tradeContractGroup.trade.IsGroup == 0 && tradeContractGroup.trade.SubTrades.Any(O => O.trade_cash == null))) { resultList.Add(new TradeDocGenerateResult(tradeContractGroup.trade) { ErrorMessage = "缺少现金交割记录" }); } else if (generatorV2 != null && !isOptionTrade) { var result = GenerateSingleV2(generatorV2, tradeContractGroup, docType); resultList.Add(result); } else { var result = GenerateSingleV1(tradeContractGroup, docType); resultList.Add(result); //if (!string.IsNullOrWhiteSpace(result.OutputFilePath)) //{ // tradeContractGroup.trade.HasGeneratedConfirmBook = 1; // var childTds = childs.Where(x => x.ParentTradeId == tradeContractGroup.trade.id); // foreach (var child in childTds) // { // child.HasGeneratedConfirmBook = 1; // } //} } } } if (generatorV2 == null) { DbContext.SaveChanges(); } return resultList; } /// /// /// private TradeDocGenerateResult GenerateSingleV2(ITradeConfirmationGenerator generator, trade_contract_group tradeContractGroup, string docType = "DOCX", List allTrades = null) { try { //修改调用的构造方法 List trades = new List(); if (allTrades != null && allTrades.Count() > 0) { trades = allTrades; }else { trades = new List() { tradeContractGroup.trade }; } List ids = new List(); if (tradeContractGroup != null && tradeContractGroup.trade != null && tradeContractGroup.trade.trade_cash != null) { ids.Add(tradeContractGroup.trade.trade_cash.id); } var context = new ConfirmationGenerateContext( ids, trades, ContractTypeEnum.Trade, OptUser, null, null); generator.Initialize(docType, context); LogFactory.GetLogger("交易确认书").Info("交易确认书init"); return generator.GenerateDocument(); } catch (Exception ex) { LogFactory.GetLogger("GenerateSingleV2").Error(ex); return new TradeDocGenerateResult(tradeContractGroup.trade) { ErrorMessage = ex.Message }; } } /// /// /// private TradeDocGenerateResult GenerateSingleV1(trade_contract_group contractGroup, string docType = "DOCX") { var logger = LogFactory.GetLogger("生成确认书详细日志"); logger.Info($"[GenerateSingleV1] 开始处理 - docType: {docType}"); if (contractGroup == null) { logger.Error("[GenerateSingleV1] contractGroup 为 null"); throw new ArgumentNullException(nameof(contractGroup)); } var trade = contractGroup.trade; logger.Info($"[GenerateSingleV1] 交易信息 - 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 = YLErp.Helpers.PathHelper.PhysicalPathToWebPath(pdfPath, OtcAppContext.RootPath) }; } return new TradeDocGenerateResult(trade) { OutputFilePath = YLErp.Helpers.PathHelper.PhysicalPathToWebPath(confirmDoc.AbsolutePath.Replace(".pdf", ".docx"), 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 { ["{{乙方名称}}"] = 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; } string strUnit = underlying.TradeUnitString; double notional = trade.Notional; dic["{{报价单位}}"] = strUnit; dic["{{商品标的数量}}"] = $"{notional}{strUnit}"; dic["{{商品标的交易所}}"] = underlying.MarketName; //价格 if (trade.ActualStrike != null) { if (trade.IsMoneynessOption == "是") { dic["{{执行价格}}"] = trade.Strike.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}期权"; if (trade.TradeType == "远期") { dic["{{期权费}}"] = $"{(trade.TradePrice * (trade.BuySell == "卖出" ? -1 : 1) ?? 0).OtcFormatMoney(grouping: false)}元"; } else { 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.OtcFormatUmPrice(); dic["{{期权费率}}"] = ((trade.PremiumRate ?? ((trade.TradePrice ?? 0) / trade.StockEqvNotional)) * 100).OtcFormatFlex(2); string 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 = DbContextFactory.GetClientDbContext(null).bankcard.FirstOrDefault(s => s.ApprovalOrder < 1 && s.ClientId == trade.ClientId && s.ValidState == "Valid"); 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 confirmLogger = LogFactory.GetLogger("生成确认书详细日志"); try { confirmLogger.Info($"[GenerateSingleConfirmBook] 开始生成 - TradeId: {trade?.id}, TradeNumber: {trade?.TradeNumber}, TradeType: {trade?.TradeType}"); confirmLogger.Info($"[GenerateSingleConfirmBook] 模板路径配置 - TradeType: {trade.TradeType}, IsUsePremiumRate: {trade.IsUsePremiumRate}"); var templateDir = OtcAppContext.MapPath("~/App_Docs/GTJA"); confirmLogger.Info($"[GenerateSingleConfirmBook] templateDir: {templateDir}"); var templatePath = OtcAppContext.MapPath("~/App_Docs/导出模板/交易确认书模板.docx"); confirmLogger.Info($"[GenerateSingleConfirmBook] 默认模板路径: {templatePath}"); if (trade.TradeType == "亚式期权") { templatePath = OtcAppContext.MapPath("~/App_Docs/导出模板/交易确认书(亚式期权)模板.docx"); confirmLogger.Info($"[GenerateSingleConfirmBook] 使用亚式期权模板: {templatePath}"); } if (trade.IsUsePremiumRate != null && trade.IsUsePremiumRate.Value) { templatePath = OtcAppContext.MapPath("~/App_Docs/导出模板/交易确认书(名义本金)模板.docx"); confirmLogger.Info($"[GenerateSingleConfirmBook] 使用名义本金模板: {templatePath}"); } confirmLogger.Info($"[GenerateSingleConfirmBook] 最终模板路径: {templatePath}"); confirmLogger.Info($"[GenerateSingleConfirmBook] 输出文件名: {outPutFileName}"); // 检查模板文件是否存在 if (!File.Exists(templatePath)) { confirmLogger.Error($"[GenerateSingleConfirmBook] 模板文件不存在: {templatePath}"); return new TradeDocGenerateResult(trade) { ErrorMessage = $"模板文件不存在: {templatePath}" }; } confirmLogger.Info($"[GenerateSingleConfirmBook] 模板文件存在,准备生成"); LogFactory.GetLogger("交易确认书").Info("交易确认书:" + outPutFileName); string outPutFilePath = Path.Combine(templateDir, outPutFileName); confirmLogger.Info($"[GenerateSingleConfirmBook] 输出文件路径: {outPutFilePath}"); // 确保输出目录存在 if (!Directory.Exists(templateDir)) { confirmLogger.Info($"[GenerateSingleConfirmBook] 创建输出目录: {templateDir}"); Directory.CreateDirectory(templateDir); } confirmLogger.Info($"[GenerateSingleConfirmBook] 调用 MsWordTempalteHelper.GenerateFromTemplate"); MsWordTempalteHelper.GenerateFromTemplate(templatePath, dic, outPutFilePath); confirmLogger.Info($"[GenerateSingleConfirmBook] MsWordTempalteHelper.GenerateFromTemplate 完成"); 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) { 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.SourceType = 1; // 系统生成 contractRecord.Paths = $"App_Docs\\GTJA\\{outPutFileName}"; contractRecord.FileName = outPutFileName; contractRecord.Type = ContractTypeEnum.Trade; contractRecord.ClientId = trade.ClientId; 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) { confirmLogger.Error($"[GenerateSingleConfirmBook] 发生异常 - TradeId: {trade?.id}, TradeNumber: {trade?.TradeNumber}", e); confirmLogger.Error($"[GenerateSingleConfirmBook] 异常类型: {e.GetType().FullName}"); confirmLogger.Error($"[GenerateSingleConfirmBook] 异常消息: {e.Message}"); confirmLogger.Error($"[GenerateSingleConfirmBook] 异常堆栈: {e.StackTrace}"); // 检查是否是内部异常 if (e.InnerException != null) { confirmLogger.Error($"[GenerateSingleConfirmBook] 内部异常类型: {e.InnerException.GetType().FullName}"); confirmLogger.Error($"[GenerateSingleConfirmBook] 内部异常消息: {e.InnerException.Message}"); confirmLogger.Error($"[GenerateSingleConfirmBook] 内部异常堆栈: {e.InnerException.StackTrace}"); } LogFactory.GetLogger().Error("GenerateSingleConfirmBook出错", e); return new TradeDocGenerateResult(trade) { ErrorMessage = e.Message }; } } public (bool, string, DateTime, string) UploadContractFile(string encryptId, string fileDescription, string ContractCode, bool OurpartySeal, bool CounterpartySeal, UploadFileModel uploadFileModel) { try { var msg = ""; #region 验证 if (string.IsNullOrWhiteSpace(encryptId)) { return (false, "请传入id", DateTime.Now, ""); } var intid = DataProtectHelper.DecryptInt(encryptId); var db = DbContextFactory.GetYLDbContext(); var contractDoc = db.trade_contract_document.Find(intid); var contractDocRArr = db.trade_contract_r.Where(O => O.ContractCode == contractDoc.Code && O.Type == contractDoc.Type && O.IsValid).ToArray(); var contractDocR = contractDocRArr.FirstOrDefault(); if (contractDoc == null || contractDocR == null) { return (false, "没有相关的确认书文档", DateTime.Now, ""); } var isExistCode = true; if (!string.IsNullOrWhiteSpace(ContractCode)) { var Codes = new List { ContractCode }; var oldDoc = db.trade_contract_document.Where(O => O.Code == ContractCode).FirstOrDefault(); isExistCode = oldDoc != null || (new TradeContractGenerateService(OptUser).GetExistsContractCode(Codes).Any()); if (isExistCode) { if (!contractDoc.Code.Equals(ContractCode)) { if (db.trade_contract_r.Where(O => O.ContractCode == ContractCode && O.IsValid).Any()) { return (false, "合约编号已存在", DateTime.Now, ""); } else { if (oldDoc != null) { db.trade_contract_document.Remove(oldDoc); isExistCode = false; } } } } msg = "修改成功"; } #endregion //var files = Request.Form.Files; if (uploadFileModel?.Length > 0) { //var file = files[0]; // var str = Encoding.UTF8.GetString(fileBytes); #region 验证 if (PS.Config.ErpElement.SecuritiesEnvironment) { if (System.IO.Path.GetExtension(uploadFileModel.FileName).ToLower() != ".xlsx" && System.IO.Path.GetExtension(uploadFileModel.FileName).ToLower() != ".xls" && System.IO.Path.GetExtension(uploadFileModel.FileName).ToLower() != ".pdf" && System.IO.Path.GetExtension(uploadFileModel.FileName).ToLower() != ".docx" && System.IO.Path.GetExtension(uploadFileModel.FileName).ToLower() != ".doc") { return (false, "请上传PDF/Word/Excel格式的文件", DateTime.Now, ""); } } if (PS.Config.ErpElement.SecuritiesEnvironment && uploadFileModel.Length > Modules.SuperviseReportModule.SAC.Model.ReportStatusModel.MaxAnnexLength)//小于30MB { return (false, "上传失败,单笔确认书文件大小不应超过30MB", DateTime.Now, ""); } #endregion var tradeNumber = "未知"; if (contractDocR != null) { tradeNumber = contractDocR.TradeNumber; } var filePath = Path.Combine(OtcAppContext.AppDocsPath, "contractdoc", YLErp.PS.Config.Company.ToString(), tradeNumber); if (!Directory.Exists(filePath)) { Directory.CreateDirectory(filePath); } #region 设置用印文件名 var stampFileFullName = Path.Combine(filePath, uploadFileModel.FileName); contractDoc.StampDocumentFileName = stampFileFullName.Replace(OtcAppContext.AppDocsPath, "/App_Docs").Replace("\\", "/"); #endregion if (File.Exists(stampFileFullName)) { File.Delete(stampFileFullName); } using var fs = new FileStream(stampFileFullName, FileMode.Create, FileAccess.ReadWrite); //using var fs = File.OpenWrite(filePath); using var sr = uploadFileModel.OpenReadStream(); sr.Seek(0, SeekOrigin.Begin); var tempBytes = new byte[sr.Length]; sr.Read(tempBytes, 0, tempBytes.Length); ////var tempstr = Encoding.UTF8.GetString(tempBytes); fs.Write(tempBytes, 0, tempBytes.Length); sr.Close(); fs.Close(); //sr.CopyTo(fs); msg = msg.Length > 0 ? msg : "上传成功"; } #region 更新数据 contractDoc.Comments = fileDescription; if (OurpartySeal && CounterpartySeal) { contractDoc.Status = ContractStatusEnum.BothPartyStamped; } else if (OurpartySeal) { contractDoc.Status = ContractStatusEnum.OurPartyStamped; } else if (CounterpartySeal) { contractDoc.Status = ContractStatusEnum.CounterPartyStamped; } else { contractDoc.Status = ContractStatusEnum.Draft; } if (!isExistCode)//默认为存在,判断 要有修改的合约编号且修改后的编号不存在 { //trade_meta var meta = db.TradeMeta.Where(O => (O.MetaKey == ConsTradeMetaKey.ContractCode || O.MetaKey.Contains("确认书")) && O.MetaValue == contractDoc.Code).FirstOrDefault(); if (meta != null) { meta.MetaValue = ContractCode; } foreach (var docR in contractDocRArr) { docR.ContractCode = ContractCode; docR.OptDate = DateTime.Now; docR.OptId = OptUser.UserId; docR.OptName = OptUser.UserName; } contractDocR.ContractCode = ContractCode; contractDocR.TradeClearCode = ContractCode; contractDoc.OptDate = DateTime.Now; contractDoc.OptId = OptUser.UserId; contractDoc.OptName = OptUser.UserName; contractDoc.Code = ContractCode; } new TradeConfirmService(OptUser, db).EditReportStatus(contractDocR.TradeId, true); db.SaveChanges(); #endregion return (true, msg, contractDoc.OptDate.Value, contractDoc.StampDocumentFileName); } catch (Exception ex) { LogFactory.GetLogger("UploadContractFile").Error("UploadContractFile出错", ex); return (false, "操作出错", DateTime.Now, ""); } } public (bool, string, DateTime, string) UploadContractFileNew(string contractCode, bool isCounterpartyDoc, UploadFileModel uploadFileModel) { try { var msg = ""; #region 验证 if (string.IsNullOrWhiteSpace(contractCode)) { return (false, "请传入参数", DateTime.Now, ""); } var db = DbContextFactory.GetYLDbContext(); var contractDoc = db.trade_contract_document.FirstOrDefault(d => d.Code == contractCode ); var contractDocRArr = db.trade_contract_r.Where(O => O.ContractCode == contractDoc.Code && O.Type == contractDoc.Type && O.IsValid).ToArray(); var contractDocRF = contractDocRArr.FirstOrDefault(); if (contractDoc == null || contractDocRF == null) { return (false, "没有相关的确认书文档", DateTime.Now, ""); } #endregion if (uploadFileModel?.Length > 0) { #region 验证 if (PS.Config.ErpElement.SecuritiesEnvironment) { if (System.IO.Path.GetExtension(uploadFileModel.FileName).ToLower() != ".xlsx" && System.IO.Path.GetExtension(uploadFileModel.FileName).ToLower() != ".xls" && System.IO.Path.GetExtension(uploadFileModel.FileName).ToLower() != ".pdf" && System.IO.Path.GetExtension(uploadFileModel.FileName).ToLower() != ".docx" && System.IO.Path.GetExtension(uploadFileModel.FileName).ToLower() != ".doc") { return (false, "请上传PDF/Word/Excel格式的文件", DateTime.Now, ""); } } if (PS.Config.ErpElement.SecuritiesEnvironment && uploadFileModel.Length > Modules.SuperviseReportModule.SAC.Model.ReportStatusModel.MaxAnnexLength)//小于30MB { return (false, "上传失败,单笔确认书文件大小不应超过30MB", DateTime.Now, ""); } #endregion var tradeNumber = "未知"; if (contractDocRF != null) { tradeNumber = contractDocRF.TradeNumber; } var filePath = Path.Combine(OtcAppContext.AppDocsPath, "contractdoc", "output"); if (!Directory.Exists(filePath)) { Directory.CreateDirectory(filePath); } var stampFileFullName = Path.Combine(filePath, uploadFileModel.FileName); contractDoc.Paths = stampFileFullName.Replace(OtcAppContext.AppDocsPath, "/App_Docs").Replace("\\", "/"); contractDoc.FileName = uploadFileModel.FileName; if (File.Exists(stampFileFullName)) { File.Delete(stampFileFullName); } using var fs = new FileStream(stampFileFullName, FileMode.Create, FileAccess.ReadWrite); using var sr = uploadFileModel.OpenReadStream(); sr.Seek(0, SeekOrigin.Begin); var tempBytes = new byte[sr.Length]; sr.Read(tempBytes, 0, tempBytes.Length); fs.Write(tempBytes, 0, tempBytes.Length); sr.Close(); fs.Close(); msg = msg.Length > 0 ? msg : "上传成功"; } #region 更新数据 contractDoc.SourceType = isCounterpartyDoc ? 2 : 1; // 对方用印文件=人工上传,否则=系统生成 var confrimService = new TradeConfirmService(OptUser, db); foreach (var contractDocR in contractDocRArr) { new TradeConfirmService(OptUser, db).EditReportStatus(contractDocR.TradeId, true); } db.SaveChanges(); #endregion return (true, msg, contractDoc.OptDate.Value, contractDoc.StampDocumentFileName); } catch (Exception ex) { LogFactory.GetLogger("UploadContractFileNew").Error("UploadContractFileNew出错", ex); return (false, "操作出错", DateTime.Now, ""); } } public string GetSealErrMsg(string code) { var db = DbContextFactory.GetYLDbContext(); var errMsg = db.trade_contract_document.FirstOrDefault(x => x.Code == code && x.SealResult == 1); return errMsg == null ? "" : errMsg.SealErrMsg; } public bool IsSealWaiting(int tradeId) { var db = DbContextFactory.GetYLDbContext(); var code = db.trade_contract_r.FirstOrDefault(x => x.TradeId == tradeId)?.ContractCode; var flag = code != null && db.trade_contract_document.Any(x => x.Code == code && x.SealResult == 3); return flag; } /// /// 判断确认书是否生成过 /// /// trade_contract_r.id /// public bool IsContractGenerated(List ids,List types) { var db = DbContextFactory.GetYLDbContext(); var flag = true; var tradeContractList = (from tradeContractR in db.trade_contract_r join tradeContractDoc in (from tradeContractDocTemp in db.trade_contract_document select tradeContractDocTemp) on tradeContractR.ContractCode equals tradeContractDoc.Code into tradeContractDoc1 from tradeContractDoc2 in tradeContractDoc1.DefaultIfEmpty() where ids.Contains(tradeContractR.id) && types.Contains(tradeContractR.Type) && tradeContractR.IsValid select new { tradeContractR.id, tradeContractR.TradeId, tradeContractR.ContractCode, tradeContractDoc = tradeContractDoc2 }).ToList(); if (tradeContractList.Count == 0 || tradeContractList.Any(x => x.tradeContractDoc == null || string.IsNullOrWhiteSpace(x.tradeContractDoc.Paths))) { flag = false; return flag; } foreach (var item in tradeContractList) { var path = Path.ChangeExtension(item.tradeContractDoc.AbsolutePath, "pdf"); if (!File.Exists(path)) { flag = false; break; } } return flag; } /// /// 批量用印 /// /// trade_contract_r.id /// public void SealContracts(List ids,List types) { var db = DbContextFactory.GetYLDbContext(); var contract = (from tradeContractR in db.trade_contract_r join tradeContractDoc in (from tradeContractDocTemp in db.trade_contract_document select tradeContractDocTemp) on tradeContractR.ContractCode equals tradeContractDoc.Code into tradeContractDoc1 from tradeContractDoc2 in tradeContractDoc1.DefaultIfEmpty() where ids.Contains(tradeContractR.id) && types.Contains(tradeContractR.Type) && tradeContractR.IsValid select new { tradeContractR.id, tradeContractR.TradeId, tradeContractR.ContractCode, tradeContractDoc = tradeContractDoc2 }).ToList(); foreach (var item in contract) { if (item.tradeContractDoc != null) { GlobalConfig.SealHandler.RemoveQueue(item.TradeId); GlobalConfig.SealHandler.AddQueue(item.tradeContractDoc, item.TradeId); } } } } }