From 48cf0592b8c49056bdb2c889debccd076e54b59f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AC=B4=E6=94=BF=20=E6=97=B6?= Date: Wed, 6 May 2026 14:33:40 +0800 Subject: [PATCH] =?UTF-8?q?=E3=80=90=E9=97=AE=E9=A2=98=E3=80=91=E4=BA=92?= =?UTF-8?q?=E6=8D=A2=E7=9A=84=E7=BB=93=E7=AE=97=E7=A1=AE=E8=AE=A4=E4=B9=A6?= =?UTF-8?q?=E7=9B=AE=E5=89=8D=E5=B1=95=E7=A4=BA=E4=BA=86=E6=9C=9F=E6=9D=83?= =?UTF-8?q?=E7=9A=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../App_Docs/settlement_template/dma_01.docx | Bin 0 -> 30096 bytes .../settlement_template/nodma_01.xlsx | Bin 0 -> 10445 bytes .../TradeSettleBillGenerator.cs | 261 +++++++++++------- .../TradeUnwindReportGenerator.cs | 143 +++++----- .../YLErp.Plugins.GuoLian.csproj | 6 + .../Scripts/app/trade/tradeApproval.js | 2 +- 6 files changed, 245 insertions(+), 167 deletions(-) create mode 100644 Plugins/YLErp.Plugins.GuoLian/App_Docs/settlement_template/dma_01.docx create mode 100644 Plugins/YLErp.Plugins.GuoLian/App_Docs/settlement_template/nodma_01.xlsx diff --git a/Plugins/YLErp.Plugins.GuoLian/App_Docs/settlement_template/dma_01.docx b/Plugins/YLErp.Plugins.GuoLian/App_Docs/settlement_template/dma_01.docx new file mode 100644 index 0000000000000000000000000000000000000000..e375ccc88a118cbb0b9c0b490ab14aae0d4d8ac0 GIT binary patch literal 30096 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 H-#+~h&#u-S literal 0 HcmV?d00001 diff --git a/Plugins/YLErp.Plugins.GuoLian/DocumentGenerator/TradeSettleBillGenerator.cs b/Plugins/YLErp.Plugins.GuoLian/DocumentGenerator/TradeSettleBillGenerator.cs index c9ef61ca..f2f1c827 100644 --- a/Plugins/YLErp.Plugins.GuoLian/DocumentGenerator/TradeSettleBillGenerator.cs +++ b/Plugins/YLErp.Plugins.GuoLian/DocumentGenerator/TradeSettleBillGenerator.cs @@ -1,8 +1,12 @@ using Newtonsoft.Json.Linq; +using YLErp.Core.Helpers; using YLErp.DBModels; +using YLErp.DBModels.Consts; +using YLErp.DBModels.Enums; using YLErp.Models; using YLErp.Plugins.TradeDocGenerator; using YLErp.Plugins.TradeDocGenerator.Abstracts; +using YLErp.QdpModule; namespace YLErp.Plugins.GuoLian.DocumentGenerator { @@ -17,123 +21,192 @@ namespace YLErp.Plugins.GuoLian.DocumentGenerator return contractNo; } - protected override string GetTemplateFilePath() - { - var templatePath = Path.Combine(GlobalConfig.PluginFolder, "App_Docs/settlement_template/settle_01.docx"); - return templatePath; - } - - protected override string GetOutputFileName(string contractNo, string contractIndex) + protected override void PrepareViewData(Dictionary dic) { var client = Context.GetClient(); var flowEvents = Context.GetFlowEvents(); - var valueDate = flowEvents.FirstOrDefault()?.UnwindDate ?? Context.SystemValueDate; - var fileName = $"结算单_{client.Name}_{valueDate:yyyyMMdd}_{contractIndex}"; - return $"{fileName}.{DocType.ToLower()}"; + var allFlowEvents = Context.GetAllFlowEvents(); + var swapPositions = Context.GetSwapPositions(); + var trades = Context.Trades; + var tradeIds = trades.Select(t => t.id).ToList(); + var tradeExtends = Context.GetTrade_Extends(tradeIds); + List table = new List(); + SwapEndConfirmModel outPut = new SwapEndConfirmModel(); + + foreach (var flowEventGroup in flowEvents) + { + var tradeId = flowEventGroup.SwapTradeId; + var positions = swapPositions.Where(x => x.SwapTradeId == tradeId && x.IsInitial).ToList(); + var posi = positions.FirstOrDefault(f => f.id == flowEventGroup.PositionId); + var unwindFlowEvents = allFlowEvents.Where(x => x.EventId == flowEventGroup.EventId); + var trade = trades.FirstOrDefault(x => x.id == tradeId); + var preSettleDate = flowEventGroup.UnwindDate.Value.AddDays(-1); + var swapEodPositions = Context.GetEodPositions(tradeId, preSettleDate); + var tradeExtend = tradeExtends.FirstOrDefault(x => x.TradeId == tradeId); + var ratio = posi.PositionType == (int)PositionTypeFlag.Long ? 1 : -1; + ExcelReportModel row = new ExcelReportModel(); + var confirmNo = Context.Gettrade_contract_r(tradeId, ContractTypeEnum.Trade); + if (string.IsNullOrEmpty(confirmNo)) + { + throw new ServiceException($"{trade.TradeNumber}未生成交易确认书"); + } + row.TradeNumber = confirmNo; + row.ClientName = client.Name; + row.UnderlyingCode = flowEventGroup.UnderlyingCode; + row.StartDate = trade.StartDate.Value.ToString("yyyy-MM-dd"); + var eventDate = flowEventGroup.UnwindDate.Value; + row.EventDate = eventDate.ToString("yyyy-MM-dd"); + var payDate = flowEventGroup.PayDate; + var sr = tradeExtend == null ? 0 : tradeExtend.ExtendObj.SettlementRules; + if (!payDate.HasValue) + { + payDate = QdpCalendarHelper.GetNonHoliday(flowEventGroup.EventDate.AddDays(sr)); + } + row.PayDate = payDate.Value.ToString("yyyy-MM-dd"); + row.ClosePrice = ((flowEventGroup.TradingAmountAvg) * 100).ToString("0.00000000"); + decimal interestRate = unwindFlowEvents.Where(x => ConsTrade.InterestModels.Contains(x.InterestMode)).Sum(s => s.InterestRate); + row.InterestRate = interestRate.ToString("0.00%"); + var PosiNotionalValue = flowEventGroup.Quantity * flowEventGroup.ContractSize * posi.PosiGrossPrice; + if (flowEventGroup.EventId.HasValue) + { + var swapEvent = Context.GetEvent(flowEventGroup.EventId.Value); + if (swapEvent != null) + { + swapEvent.unwindData = JsonHelper.Deserialize(swapEvent.EventData); + PosiNotionalValue = swapEvent.unwindData.CloseNotionalValue; + } + } + + row.Quantity = flowEventGroup.Quantity.ToString("0.00"); + row.PosiNotionalValue = PosiNotionalValue.ToString("0.00"); + row.PosiNetPrice = (posi.PosiGrossPrice * 100).ToString("0.00000000"); + //var tradingFee = (flowEventGroup.TradingAmountFeeAvg- posi.PosiNetPrice- flowEventGroup.TradingAmountAvg+ posi.PosiGrossPrice)* PosiNotionalValue* ratio; + var tradingFee = flowEventGroup.TradingFee + flowEventGroup.TradingFeePending; + row.Fee = (-tradingFee).ToString("0.00"); + var RateDays = (eventDate - trade.StartDate.Value).Days; + RateDays = RateDays < 0 ? 0 : RateDays; + row.RateDays = RateDays.ToString(); + var MarginAmout = positions.Where(x => x.InterestMode == (int)InterestModeEnum.初始预付金).Sum(s => s.InterestPrincipalFix * (s.InterestDirection == (int)SwapDirectionEnum.收取 ? 1 : -1)); + row.MarginAmout = Math.Abs(MarginAmout).ToString("0.00"); + var MarginRebateRate = positions.Where(x => x.InterestMode == (int)InterestModeEnum.初始预付金).Sum(s => s.InterestRateDefault); + row.MarginRebateRate = MarginRebateRate.ToString("0.00%"); + + var MarginInterestAmount = unwindFlowEvents.Where(x => ConsTrade.InterestMarginModels.Contains(x.InterestMode)).Sum(s => s.InterestClosePnL); + row.MarginInterestAmount = (-MarginInterestAmount).ToString("0.00"); + + var InterestAmount = unwindFlowEvents.Where(x => ConsTrade.InterestModels.Contains(x.InterestMode)).Sum(s => s.InterestClosePnL) * -1; + row.InterestAmount = InterestAmount.ToString("0.00"); + + //var lastInterestAmount= swapEodPositions.Where(x => ConsTrade.InterestModels.Contains(x.InterestMode)).Sum(s => s.InterestIncomeSum); + //var lastPosiNotionalValue = swapEodPositions.Sum(s=>s.PosiNotionalValue); + //var InterestAmount = lastPosiNotionalValue==0?0: - lastInterestAmount* PosiNotionalValue/ lastPosiNotionalValue; + //row.InterestAmount = InterestAmount.ToString("0.00"); + + //var lastMarginAmount = swapEodPositions.Where(x => ConsTrade.InterestMarginModels.Contains(x.InterestMode)).Sum(s => s.InterestIncomeSum); + //var MarginInterestAmount = lastMarginAmount == 0 ? 0 : -lastMarginAmount * PosiNotionalValue / lastMarginAmount; + //row.MarginInterestAmount = MarginInterestAmount.ToString("0.00"); + var FloatRate = PosiNotionalValue == 0 ? 0 : InterestAmount / PosiNotionalValue; + row.FloatRate = FloatRate.ToString("0.0000%"); + var PosiPnl = -(flowEventGroup.MarkClosePnl - tradingFee - flowEventGroup.DividendIn); + row.PosiPnl = PosiPnl.ToString("0.00"); + var markClosePnl = (-flowEventGroup.MarkClosePnl); + row.MarkClosePnl = markClosePnl.ToString("0.00"); + row.DividendIn = (-flowEventGroup.DividendIn).ToString("0.00"); + var marginBackAmount = unwindFlowEvents.Where(x => ConsTrade.InterestMarginModels.Contains(x.InterestMode)).Sum(s => s.InterestPrincipal); + var NetSettleAmout = unwindFlowEvents.Sum(x => x.InterestClosePnL) * -1 + flowEventGroup.MarkClosePnl * -1 + marginBackAmount; + row.NetSettleAmout = NetSettleAmout.ToString("0.00"); + table.Add(row); + } + outPut.table = table; + dic["TRS结算单"] = outPut; + } protected override void PrepareViewData(Dictionary dic) { var client = Context.GetClient(); - var trades = Context.Trades; - var trade = trades.FirstOrDefault(); + if (string.IsNullOrEmpty(client.SettleFileNumber)) + { + throw new ServiceException($"{client.Name}未设置定义文件编号"); + } var flowEvents = Context.GetFlowEvents(); var allFlowEvents = Context.GetAllFlowEvents(); - - // 基础信息 - dic["客户名称"] = client.Name; - dic["乙方名称"] = client.Name; - - var eventDate = flowEvents.FirstOrDefault()?.UnwindDate; - dic["结算日期"] = eventDate?.ToString("yyyy年M月d日") ?? DateTime.Now.ToString("yyyy年M月d日"); - - // 交易信息 - dic["交易编号"] = trade?.TradeNumber ?? ""; - dic["交易类型"] = trade?.TradeType ?? ""; - dic["标的代码"] = trade?.UnderlyingCode ?? ""; - - var underlying = trade != null ? Context.GetTradeUnderlying(trade.UnderlyingCode) : null; - if (underlying != null) + var swapPositions = Context.GetSwapPositions(); + var trades = Context.Trades; + var eventDate = flowEvents.First().UnwindDate; + var td = trades.First(); + var realPositions = swapPositions.Where(x => x.PosiQuantity > 0 && !x.IsInitial).ToList(); + var posiNationalValue = realPositions.Sum(x => x.PosiNotionalValue); + var metaDic = Context.GetTradeMetas(td.id); + dic["主协议编号"] = metaDic[ConsTradeMetaKey.MainProtocolCode]; + dic["文件编号"] = client.SettleFileNumber; + dic["乙方"] = client.Name; + dic["管理人名称"] = client.Manager; + var confirmNo = Context.Gettrade_contract_r(td.id, ContractTypeEnum.Trade); + if (string.IsNullOrEmpty(confirmNo)) { - dic["标的名称"] = underlying.UnderlyingName; + throw new ServiceException($"{td.TradeNumber}未生成交易确认书"); } - - // 结算金额 - 从 flow events 计算 - var flowEvent = flowEvents.FirstOrDefault(); - if (flowEvent != null) + FormatToDict("平仓日期", eventDate, dic); + JArray table = new JArray(); + JArray table2 = new JArray(); + foreach (var flowEvent in flowEvents) { - var unwindFlowEvents = allFlowEvents.Where(x => x.EventId == flowEvent.EventId); - var NetSettleAmout = unwindFlowEvents.Sum(x => x.InterestClosePnL) * -1 - + flowEvent.MarkClosePnl * -1; - - dic["结算金额"] = NetSettleAmout.ToString("N2"); - dic["结算金额大写"] = Context.CmycurD(Math.Abs((double)NetSettleAmout)); - dic["结算价格"] = flowEvent.TradingAmountAvg.ToString("N4"); - dic["结算比例"] = "0.00%"; + var tradeId = flowEvent.SwapTradeId; + var positions = swapPositions.Where(x => x.SwapTradeId == tradeId).ToList(); + var posi = positions.FirstOrDefault(f => f.PositionId == flowEvent.PositionId); + JObject row = new JObject(); + row["交易确认书编号"] = confirmNo; + var ratio = flowEvent.PositionType == (int)PositionTypeFlag.Long ? 1 : -1; + row["多空方向"] = flowEvent.PositionType == (int)PositionTypeFlag.Long ? "多" : "空"; + FormatToDict("平仓日期", eventDate, row); + underlying_manager underlying = Context.GetTradeUnderlying(flowEvent.UnderlyingCode); + row["标的代码"] = flowEvent.UnderlyingCode; + row["标的名称"] = underlying?.UnderlyingName; + var preQty = flowEvent.Quantity + flowEvent.PositionQty ?? 0; + FormatToDict("平仓前数量", Convert.ToDouble(preQty) * ratio, row); + FormatToDict("平仓数量", Convert.ToDouble(flowEvent.Quantity), row); + FormatToDict("平仓后数量", Convert.ToDouble(flowEvent.PositionQty ?? 0) * ratio, row); + FormatToDict("平仓成交金额", Convert.ToDouble(flowEvent.Quantity * posi.PosiNetPrice * flowEvent.ContractSize), row); + table.Add(row); } - else + JObject row2 = new JObject(); + row2["交易确认书编号"] = confirmNo; + FormatToDict("平仓日期", eventDate, row2); + FormatToDict("平仓后名义本金", Convert.ToDouble(posiNationalValue), row2); + table2.Add(row2); + dic["table"] = table; + dic["table2"] = table2; + } + protected override string GetTemplateFilePath() + { + var trades = Context.Trades; + var templatePath = string.Empty; + if (trades.Any(s => s.StructureType == "多空组合" || s.StructureType == "定义文件型债券收益互换")) { - dic["结算金额"] = "0.00"; - dic["结算金额大写"] = Context.CmycurD(0); - dic["结算价格"] = "0.0000"; - dic["结算比例"] = "0.00%"; + templatePath = MosPathHelper.Combine(GlobalConfig.PluginFolder, "App_Docs/settlement_template/dma_01.docx"); + return templatePath; } - - // 名义本金 - dic["名义本金"] = trade?.OriginalStockEqvNotional?.ToString("N2") ?? "0.00"; - - // 表格数据 - var table1 = new JArray(); - foreach (var fe in flowEvents) - { - var unwindFlowEvents = allFlowEvents.Where(x => x.EventId == fe.EventId); - var netAmount = unwindFlowEvents.Sum(x => x.InterestClosePnL) * -1 + fe.MarkClosePnl * -1; - var row = new JObject - { - ["交易编号"] = trade?.TradeNumber ?? "", - ["交易类型"] = trade?.TradeType ?? "", - ["标的代码"] = fe.UnderlyingCode ?? trade?.UnderlyingCode ?? "", - ["标的名称"] = underlying?.UnderlyingName ?? "", - ["结算金额"] = netAmount.ToString("N2") - }; - table1.Add(row); - } - dic["table1"] = table1; + templatePath = MosPathHelper.Combine(GlobalConfig.PluginFolder, "App_Docs/settlement_template/nodma_01.xlsx"); + return templatePath; } - protected override void PrepareViewData(Dictionary dic) + protected override string GetOutputFileName(string contractNo, string contractIndex) { - var client = Context.GetClient(); var trades = Context.Trades; - var trade = trades.FirstOrDefault(); + var client = Context.GetClient(); var flowEvents = Context.GetFlowEvents(); - var allFlowEvents = Context.GetAllFlowEvents(); - - dic["客户名称"] = client.Name; - var eventDate = flowEvents.FirstOrDefault()?.UnwindDate; - dic["结算日期"] = eventDate?.ToString("yyyy-MM-dd") ?? DateTime.Now.ToString("yyyy-MM-dd"); - dic["交易编号"] = trade?.TradeNumber ?? ""; - dic["交易类型"] = trade?.TradeType ?? ""; - dic["标的代码"] = trade?.UnderlyingCode ?? ""; - - var underlying = trade != null ? Context.GetTradeUnderlying(trade.UnderlyingCode) : null; - dic["标的名称"] = underlying?.UnderlyingName ?? ""; - - var flowEvent = flowEvents.FirstOrDefault(); - if (flowEvent != null) + var eventDate = flowEvents.FirstOrDefault().UnwindDate.Value; + var valueDate = eventDate.ToString("yyyy-MM-dd"); + var count = Context.GetDMASelttementCount(client.id, eventDate); + var countStr = count == 0 ? "" : "-" + (count + 1).ToString(); + var FullName = $"结算单-{client.Name}-{valueDate}{countStr}"; + if (trades.Any(s => s.StructureType == "多空组合" || s.StructureType == "定义文件型债券收益互换")) { - var unwindFlowEvents = allFlowEvents.Where(x => x.EventId == flowEvent.EventId); - var NetSettleAmout = unwindFlowEvents.Sum(x => x.InterestClosePnL) * -1 + flowEvent.MarkClosePnl * -1; - dic["结算金额"] = NetSettleAmout; - dic["结算价格"] = flowEvent.TradingAmountAvg; + FullName = $"{client.Name}-结算确认书-{valueDate}-交易平仓{countStr}"; + return $"{FullName}.docx"; } - else - { - dic["结算金额"] = 0; - dic["结算价格"] = 0; - } - - dic["名义本金"] = trade?.OriginalStockEqvNotional ?? 0; + return $"{FullName}.xlsx"; } } } diff --git a/Plugins/YLErp.Plugins.GuoLian/DocumentGenerator/TradeUnwindReportGenerator.cs b/Plugins/YLErp.Plugins.GuoLian/DocumentGenerator/TradeUnwindReportGenerator.cs index 6cf6c32d..9e7a740f 100644 --- a/Plugins/YLErp.Plugins.GuoLian/DocumentGenerator/TradeUnwindReportGenerator.cs +++ b/Plugins/YLErp.Plugins.GuoLian/DocumentGenerator/TradeUnwindReportGenerator.cs @@ -6,7 +6,7 @@ using YLErp.Plugins.TradeDocGenerator.Abstracts; namespace YLErp.Plugins.GuoLian.DocumentGenerator { /// - /// 国联证券了结报告生成器 + /// ֤ȯ˽ᱨ /// internal class TradeUnwindReportGenerator : BaseUnwindReportGenerator, ITradeUnwindReportGenerator { @@ -17,124 +17,123 @@ namespace YLErp.Plugins.GuoLian.DocumentGenerator } /// - /// 准备Word模板数据 + /// ׼Wordģ /// protected override void PrepareViewData(Dictionary dic) { var table1 = new JArray(); var trade = Context.Trade; var client = Context.GetClient(); - var valueTimeList = new List(); + var valuetimelist = new List(); var underlying = Context.GetTradeUnderlying(); + var variety = Context.GetUnderlyingVariety(); var tradeCash = Context.GetTradeCash(); - var tradeList = Context.Trades.Union(Context.SubTrades).ToList(); - + var instrumentTypeArr = new List() { ConsGlobal.InstrumentType.Stock, ConsGlobal.InstrumentType.StockIndex, ConsGlobal.InstrumentType.StockIF }; + var tradelist = Context.Trades.Union(Context.SubTrades).ToList(); foreach (var item in Context.Trades) { - foreach (var tradeCashItem in Context.TradeCashes[item.id]) + foreach (var tradeCashs in Context.TradeCashes[item.id]) { - var settlementPrice = (trade.IsUsePremiumRate != null && trade.IsUsePremiumRate.Value - ? tradeCashItem.UnwindPricePercentRate.OtcFormatPercent() - : tradeCashItem.UnwindPrice.OtcFormatMoney()); - + var settlementprice = (trade.IsUsePremiumRate != null && trade.IsUsePremiumRate.Value ? tradeCashs.UnwindPricePercentRate.OtcFormatPercent() : tradeCashs.UnwindPrice.OtcFormatMoney()); var row = new JObject(); - var currentTrade = tradeList.Find(o => o.id == tradeCashItem.TradeId); - - row["交易编号"] = currentTrade?.TradeNumber ?? ""; - - // 买卖方向处理 + OtcTradeBase trades = tradelist.Find(O => O.id == tradeCashs.TradeId); + row["ױ"] = trades.TradeNumber; switch (item.BuySell) { - case "买入": - row["买方"] = (trade.OpponentRole == null || trade.OpponentRole == "乙方") ? "甲方" : "乙方"; + case "": + if (trade.OpponentRole == null || trade.OpponentRole == "ҷ") + { + row[""] = $"׷"; + } + else + { + row[""] = $"ҷ"; + } break; - case "卖出": - row["买方"] = (trade.OpponentRole == null || trade.OpponentRole == "乙方") ? "乙方" : "甲方"; + case "": + if (trade.OpponentRole == null || trade.OpponentRole == "ҷ") + { + row[""] = $"ҷ"; + } + else + { + row[""] = $"׷"; + } break; default: - row["买方"] = ""; break; } + row[""] = $"{trades.TradeDate:yyyy/MM/dd}"; + row["ʼ"] = $"{trades.StartDate:yyyy/MM/dd}-{trades.ExerciseDate:yyyy/MM/dd}"; + row["屾"] = $"{trades.OriginalStockEqvNotional.OtcFormatMoney()}"; + row["Ĵ"] = $"{trades.UnderlyingCode}"; + row["Ȩ"] = $"{trades.TradeType}"; + row["ڳ۸"] = $"{trades.TradePrice.OtcFormatMoney()}"; + row[""] = $"{tradeCashs.ValueDate:yyyy/MM/dd}"; + row["۸"] = $"{tradeCashs.FinalPrice.OtcFormatMoney()}"; + row["ģ"] = $"{(tradeCashs.UnwindPercentRate * trades.OriginalNotional * underlying.CountRatio).OtcFormatMoney()}"; + row["㵥"] = $"{settlementprice}"; + var Amountqrs = -tradeCashs.Amount; + var Amountqrs2 = -(tradeCashs.Amount + (trades.TradePrice ?? 0) * (tradeCashs.UnwindPercentRate ?? 0) * ((trades.BuySell == "") ? 1 : -1)); - row["交易日期"] = currentTrade?.TradeDate?.ToString("yyyy/MM/dd") ?? ""; - row["开始日期"] = $"{currentTrade?.StartDate:yyyy/MM/dd}-{currentTrade?.ExerciseDate:yyyy/MM/dd}"; - row["名义本金"] = currentTrade?.OriginalStockEqvNotional.OtcFormatMoney() ?? "0.00"; - row["标的代码"] = currentTrade?.UnderlyingCode ?? ""; - row["期权类型"] = currentTrade?.TradeType ?? ""; - row["期初价格"] = currentTrade?.TradePrice.OtcFormatMoney() ?? "0.00"; - row["结算日期"] = tradeCashItem.ValueDate.ToString("yyyy/MM/dd"); - row["结算价格"] = tradeCashItem.FinalPrice.OtcFormatMoney(); - row["结算模块"] = ((tradeCashItem.UnwindPercentRate ?? 0) * (currentTrade?.OriginalNotional ?? 0) * (underlying?.CountRatio ?? 0)).OtcFormatMoney() ?? "0.00"; - row["结算单价"] = settlementPrice; - - var amountQrs = -tradeCashItem.Amount; - var amountQrs2 = -(tradeCashItem.Amount + (currentTrade?.TradePrice ?? 0) * (tradeCashItem.UnwindPercentRate ?? 0) * ((currentTrade?.BuySell == "卖出") ? 1 : -1)); - - row["结算期权费"] = amountQrs.OtcFormatMoney(); - row["结算金额"] = amountQrs2.OtcFormatMoney(); - + row["Ȩ"] = $"{Amountqrs.OtcFormatMoney()}"; + row[""] = $"{Amountqrs2.OtcFormatMoney()}"; table1.Add(row); - valueTimeList.Add(tradeCashItem.ValueDate); + valuetimelist.Add(tradeCashs.ValueDate); } } - - // 合同编号由基类统一设置,此处不再重复生成 + dic["ͬ"] = Context.GenerateContractNo(out _); dic["table1"] = table1; - dic["合同日期"] = DateTime.Now.ToString("yyyy/MM/dd"); - dic["了结日期1"] = valueTimeList.Min().ToString("yyyy/MM/dd"); - dic["了结日期2"] = valueTimeList.Max().ToString("yyyy/MM/dd"); + dic["ͬ"] = $"{DateTime.Now.ToString("yyyy/MM/dd")}";//ValueDate + dic["˽1"] = $"{valuetimelist.Min():yyyy/MM/dd}"; + dic["˽2"] = $"{valuetimelist.Max():yyyy/MM/dd}"; - // 甲乙方信息 - var ownerInfo = Context.GetOwner_info("默认"); - dic["客户名称"] = client?.Name ?? ""; - dic["公司名称"] = ownerInfo?.FullName ?? ""; + #region ҷϢж - if (trade.OpponentRole == null || trade.OpponentRole == "乙方") + + var owner_Info = Context.GetOwner_info("Ĭ"); + dic["ͻ"] = client != null ? client.Name : ""; + dic["˾"] = owner_Info != null ? owner_Info.FullName != null ? owner_Info.FullName : "" : ""; + if (trade.OpponentRole == null || trade.OpponentRole == "ҷ") { - dic["甲方"] = ownerInfo?.FullName ?? ""; - dic["乙方"] = client?.Name ?? ""; + dic["׷"] = owner_Info != null ? owner_Info.FullName != null ? owner_Info.FullName : "" : ""; + dic["ҷ"] = client != null ? client.Name : ""; } else { - dic["甲方"] = client?.Name ?? ""; - dic["乙方"] = ownerInfo?.FullName ?? ""; + dic["׷"] = client != null ? client.Name : ""; + dic["ҷ"] = owner_Info != null ? owner_Info.FullName != null ? owner_Info.FullName : "" : ""; } + + #endregion } - /// - /// 获取模板文件路径 - /// protected override string GetTemplateFilePath() { - var templatePath = Path.Combine(GlobalConfig.PluginFolder, "App_Docs\\settlement_template\\unwind_01.docx"); + var templatePath = ""; + templatePath = Path.Combine(GlobalConfig.PluginFolder, "App_Docs/settlement_template/settle_01.docx"); return templatePath; } - /// - /// 获取输出文件名 - /// protected override string GetOutputFileName(string contractNo, string contractIndex) { var client = Context.GetClient(); var trade = Context.Trade; - var tradeList = Context.Trades.Union(Context.SubTrades).ToList(); - var ownerInfo = Context.GetOwner_info("默认") ?? new Owner_info(); - - var maxTradeDate = tradeList.Max(m => m.TradeDate); - var minTradeDate = tradeList.Min(m => m.TradeDate); - - string date; - if (maxTradeDate == minTradeDate) + var tradelist = Context.Trades.Union(Context.SubTrades).ToList(); + var owner_Info = Context.GetOwner_info("Ĭ") ?? new Owner_info(); + var dts = tradelist.Max(m => m.TradeDate); + var dte = tradelist.Min(m => m.TradeDate); + var date = ""; + if (dts == dte) { - date = trade.TradeDate?.ToString("yyyyMMdd") ?? DateTime.Now.ToString("yyyyMMdd"); + date = trade.TradeDate?.ToString("yyyyMMdd"); } else { - date = $"{minTradeDate:yyyyMMdd}-{maxTradeDate:yyyyMMdd}"; + date = dts?.ToString("yyyyMMdd") + "-" + dte?.ToString("yyyyMMdd"); } - - var fullName = ownerInfo?.FullName ?? ""; - var rule = $"{fullName} {trade.TradeType}结算确认书 {date}"; + var FullName = owner_Info != null ? owner_Info.FullName != null ? owner_Info.FullName : "" : ""; + var rule = $"{FullName}{trade.TradeType}ȷ{date}"; Context.GetcontractIndex(rule, out var contractIndex2); return $"{rule}-{contractIndex2}.{DocType.ToLower()}"; } diff --git a/Plugins/YLErp.Plugins.GuoLian/YLErp.Plugins.GuoLian.csproj b/Plugins/YLErp.Plugins.GuoLian/YLErp.Plugins.GuoLian.csproj index 58b7c9f7..5832ff46 100644 --- a/Plugins/YLErp.Plugins.GuoLian/YLErp.Plugins.GuoLian.csproj +++ b/Plugins/YLErp.Plugins.GuoLian/YLErp.Plugins.GuoLian.csproj @@ -26,6 +26,12 @@ PreserveNewest + + PreserveNewest + + + PreserveNewest + PreserveNewest diff --git a/YLErpWeb/wwwroot/Scripts/app/trade/tradeApproval.js b/YLErpWeb/wwwroot/Scripts/app/trade/tradeApproval.js index 4dfc4855..47e66ab8 100644 --- a/YLErpWeb/wwwroot/Scripts/app/trade/tradeApproval.js +++ b/YLErpWeb/wwwroot/Scripts/app/trade/tradeApproval.js @@ -168,7 +168,7 @@ var colModelGrid = [ sortable: false, formatter: function (cellvalue, options, rowObject) { if (rowObject.TradeType === "收益互换") { - return otcformat.trading.umprice(cellvalue) * 100 + "%"; + return otcformat.flex(otcformat.trading.umprice(cellvalue), 2, 9, true, false, true); } return otcformat.trading.umprice(cellvalue); }