diff --git a/Plugins/YLErp.Plugins.ZheShang/App_Docs/交易确认书/客户多头交易确认书模板.docx b/Plugins/YLErp.Plugins.ZheShang/App_Docs/交易确认书/客户多头交易确认书模板.docx new file mode 100644 index 00000000..711f4173 Binary files /dev/null and b/Plugins/YLErp.Plugins.ZheShang/App_Docs/交易确认书/客户多头交易确认书模板.docx differ diff --git a/Plugins/YLErp.Plugins.ZheShang/App_Docs/交易确认书/客户空头交易确认书模板.docx b/Plugins/YLErp.Plugins.ZheShang/App_Docs/交易确认书/客户空头交易确认书模板.docx new file mode 100644 index 00000000..15bbd574 Binary files /dev/null and b/Plugins/YLErp.Plugins.ZheShang/App_Docs/交易确认书/客户空头交易确认书模板.docx differ diff --git a/Plugins/YLErp.Plugins.ZheShang/App_Docs/交易确认书/收益互换交易确认书(DMA)模板.docx b/Plugins/YLErp.Plugins.ZheShang/App_Docs/交易确认书/收益互换交易确认书(DMA)模板.docx new file mode 100644 index 00000000..88e51041 Binary files /dev/null and b/Plugins/YLErp.Plugins.ZheShang/App_Docs/交易确认书/收益互换交易确认书(DMA)模板.docx differ diff --git a/Plugins/YLErp.Plugins.ZheShang/App_Docs/结算单/DMA结算单.docx b/Plugins/YLErp.Plugins.ZheShang/App_Docs/结算单/DMA结算单.docx new file mode 100644 index 00000000..8b2eef7a Binary files /dev/null and b/Plugins/YLErp.Plugins.ZheShang/App_Docs/结算单/DMA结算单.docx differ diff --git a/Plugins/YLErp.Plugins.ZheShang/App_Docs/结算单/场外衍生品结算确认书.docx b/Plugins/YLErp.Plugins.ZheShang/App_Docs/结算单/场外衍生品结算确认书.docx new file mode 100644 index 00000000..56ec3f15 Binary files /dev/null and b/Plugins/YLErp.Plugins.ZheShang/App_Docs/结算单/场外衍生品结算确认书.docx differ diff --git a/Plugins/YLErp.Plugins.ZheShang/App_Docs/结算单/非DMA结算单.xlsx b/Plugins/YLErp.Plugins.ZheShang/App_Docs/结算单/非DMA结算单.xlsx new file mode 100644 index 00000000..81ac1c92 Binary files /dev/null and b/Plugins/YLErp.Plugins.ZheShang/App_Docs/结算单/非DMA结算单.xlsx differ diff --git a/Plugins/YLErp.Plugins.ZheShang/DocumentGenerator/TradeConfirmationGenerator.cs b/Plugins/YLErp.Plugins.ZheShang/DocumentGenerator/TradeConfirmationGenerator.cs new file mode 100644 index 00000000..889b03ec --- /dev/null +++ b/Plugins/YLErp.Plugins.ZheShang/DocumentGenerator/TradeConfirmationGenerator.cs @@ -0,0 +1,306 @@ +using Newtonsoft.Json.Linq; +using System.Text.RegularExpressions; +using YLErp.Core.Helpers; +using YLErp.DBModels; +using YLErp.DBModels.Consts; +using YLErp.Enums; +using YLErp.Plugins.TradeDocGenerator; +using YLErp.Plugins.TradeDocGenerator.Abstracts; + +namespace YLErp.Plugins.ShanXi.DocumentGenerator +{ + internal class TradeConfirmationGenerator : BaseConfirmationGenerator, ITradeConfirmationGenerator + { + public TradeConfirmationGenerator() + : base(ContractTypeEnum.Trade) + { + + } + + protected override string GetTemplateFilePath() + { + string templatePath = null; + var trade = Context.Trade; + if (trade.TradeType == "收益互换" && trade.StructureType != null) + { + if (trade.StructureType == "普通债券类收益互换"|| trade.StructureType == "普通收益互换") + { + var swapPosition = Context.GetSwapPositions(trade.id, true).Where(x => x.PositionType>0).FirstOrDefault(); + + if (swapPosition != null) + { + switch (swapPosition.PositionType) + { + case 1: + templatePath = MosPathHelper.Combine(GlobalConfig.PluginFolder, "App_Docs\\交易确认书\\客户多头交易确认书模板.docx"); + break; + case 2: + templatePath = MosPathHelper.Combine(GlobalConfig.PluginFolder, "App_Docs\\交易确认书\\客户空头交易确认书模板.docx"); + break; + } + } + } + else + { + templatePath = MosPathHelper.Combine(GlobalConfig.PluginFolder, "App_Docs\\交易确认书\\收益互换交易确认书(DMA)模板.docx"); + } + } + else + { + throw new Exception("不支持商品类型"); + } + return templatePath; + } + + protected override string GetOutputFileName(string contractNo, string contractIndex) + { + var rule = $"收益互换交易确认书{contractNo}"; + return $"{rule}.{DocType.ToLower()}"; + } + + protected override string GetContractNo(out string contractIndex) + { + var contractNo = Context.GenerateContractNo(out contractIndex); + return contractNo; + } + + protected override void PrepareViewData(Dictionary dic) + { + var trade = Context.Trade; + switch (trade.IsGroup == 1 ? trade.StructureType : trade.TradeType) + { + case "收益互换": + SetSwapData(dic); + break; + default: + break; + } + } + + + /// + /// 检查是否存在扩展模板 + /// + /// + private string CheckTemplateFilePath(string templateFilePath, OtcTradeBase t) + { + bool check(string pathStr, string tempName, string suffix, out string nPath) + { + nPath = $"{pathStr}{tempName}{suffix}"; + return File.Exists(nPath); + }; + + var fix = Path.GetExtension(templateFilePath); + var path = $"{Path.GetDirectoryName(templateFilePath)}\\{Path.GetFileNameWithoutExtension(templateFilePath)}"; + if (check(path, t.OptionType, fix, out var newPath)) + { + templateFilePath = newPath; + } + + return templateFilePath; + } + /// + /// 山证收益互换模板数据填充 + /// + /// + public void SetSwapData(Dictionary dic) + { + var trade = Context.Trade; + if (trade.StructureType == "普通债券类收益互换" || trade.StructureType == "普通收益互换") + { + SetSingleSwap(dic); + } + else + { + SetLongShort(dic); + } + + + } + + private void SetSingleSwap(Dictionary dic) + { + var client = Context.GetClient(); + var trade = Context.Trade; + var bank = Context.GetClientBankCard(false); + var clientduties = Context.GetClientDuties(); + var swapPositions = Context.GetSwapPositions(trade.id, true); + var swapPosition = swapPositions.Where(x => x.PositionType == 1 || x.PositionType == 2).FirstOrDefault(); + var interestMargin = swapPositions.Where(x => ConsTrade.InterestModels.Contains(x.InterestMode)).FirstOrDefault(); + var initialMarginQuery = swapPositions.Where(x => x.InterestMode == 5); + var additionMarginQuery = swapPositions.Where(x => x.InterestMode == 6); + var underlyingCode = swapPosition?.UnderlyingCode; + var table1 = new JArray(); + var table2 = new JArray(); + var clientMarginRate = Context.GetClientMarginRate(client.id); + + dic["交易编号"] = trade.TradeNumber; + dic["交易对手方全称"] = client.ClientType != "产品" ? client.Name : $"{client.Manager}作为管理人代表{client.Name}"; + dic["主协议编号"] = client.MainProtocolCode; + dic["定义文件编号"] = client.SettleFileNumber; + FormatToDict("名义本金", trade.StockEqvNotionalReal, dic); + dic["成交日期"] = trade.TradeDate?.ToString("【yyyy】年【M】月【d】日"); + dic["开始日期"] = trade.StartDate?.ToString("【yyyy】年【M】月【d】日"); + dic["到期日期"] = trade.ExerciseDate?.ToString("【yyyy】年【M】月【d】日"); + dic["成交日期2"] = trade.TradeDate?.ToString("【yyyy】年【M】月【d】日"); + dic["户名"] = bank?.ClientName; + dic["银行账号"] = bank?.Card; + dic["开户行"] = bank?.Bank; + dic["大额行号"] = bank?.Payment; + + FormatToDict("期初标的交割全价", (double)((swapPosition?.PosiGrossPrice) ?? 0) * 100, dic); + FormatToDict("期初标的交割净价", (double)((swapPosition?.PosiNetNoFeePrice) ?? 0) * 100, dic); + dic["利差"] = ((interestMargin?.InterestRateDefault) ?? 0) * 100; + var basicFee = trade.StockEqvNotionalReal == 0 ? 0 : ((double)((swapPosition?.PosiTradingFeePending) ?? 0) / trade.StockEqvNotionalReal) * 100; + dic["基本费率"] = (basicFee * 2).ToString("f4"); + var initialMarginSum = initialMarginQuery.Sum(x => + x.InterestDirection == 2 ? x.InterestPrincipalFix * -1 : x.InterestPrincipalFix); + FormatToDict("交易费用", (double)((swapPosition?.PosiTradingFeePending * 2) ?? 0), dic); + dic["交易费率"] = dic["基本费率"]; + FormatToDict("期初预付金", (double)initialMarginSum, dic); + dic["期初预付金利率"] = ((initialMarginQuery.FirstOrDefault()?.InterestRateDefault) ?? 0) * 100; + dic["追加预付金返息率"] = ((clientMarginRate?.AddToMarginRebateRate) ?? 0) * 100; + + dic["标的代码"] = underlyingCode; + + dic["标的名称"] = Context.GetTradeUnderlying(underlyingCode).UnderlyingName; + + var bond = JsonHelper.Deserialize(Context.GetTradeUnderlying(underlyingCode).ExJson) ?? + new UnderlyingBond(); + dic["标的发行人"] = bond.UnderlyingIssuer; + + clientduties = clientduties.Where(x=> x.ContactTypeId.Contains("3")).OrderBy(o=>o.id).ToList();//交易下达人 + if (clientduties.Count>0) + { + var clientduty= clientduties.First(); + var row = new JObject(); + row["姓名"] = clientduty.ContactName; + row["身份证号"] = clientduty.IdCardNo; + row["联系电话"] = clientduty.PhoneNumber; + row["电子邮箱"] = clientduty.Email; + row["传真"] = clientduty.Fax; + + table2.Add(row); + } + dic["table2"] = table2; + } + + private void SetLongShort(Dictionary dic) + { + var client = Context.GetClient(); + var trade = Context.Trade; + var swapPositions = Context.GetSwapPositions(trade.id, true); + var swapFlowDeals = Context.GetSwapFlowDeals(trade.id); + swapFlowDeals = swapFlowDeals.Where(x => x.OpenFlag==(int)OpenCloseEnum.开仓).ToList(); + var table1 = new JArray(); + var table2 = new JArray(); + + dic["交易编号"] = trade.TradeNumber; + dic["交易对手方全称"] = client.Name; + dic["主协议编号"] = client.MainProtocolCode; + dic["定义文件编号"] = client.SettleFileNumber; + //FormatToDict("名义本金", trade.StockEqvNotionalReal, dic); + dic["成交日期"] = trade.TradeDate?.ToString("yyyy年M月d日"); + dic["开始日期"] = trade.StartDate?.ToString("yyyy年M月d日"); + dic["到期日期"] = trade.ExerciseDate?.ToString("yyyy年M月d日"); + var count = 0; + var count2 = 0; + var interestMode = new int[] { 1, 2, 7, 8 }; + var list = swapPositions.Where(x => x.PositionType > 0 && x.PosiQuantity > 0); + + var fixLong = swapPositions.Where(x => x.InterestMode == 7).FirstOrDefault(); + var fixShort = swapPositions.Where(x => x.InterestMode == 8).FirstOrDefault(); + dic["固定多头"] = ((double)(fixLong?.InterestRateDefault * 100 ?? 0)).ToString("0.####") + "%"; + dic["浮动多头"] = !string.IsNullOrWhiteSpace(fixLong?.FloatRateUnderlyingCode) ? "适用" : "不适用"; + dic["固定空头"] = ((double)(fixShort?.InterestRateDefault * 100 ?? 0)).ToString("0.####") + "%"; + dic["浮动空头"] = !string.IsNullOrWhiteSpace(fixShort?.FloatRateUnderlyingCode) ? "适用" : "不适用"; + dic["管理人名称"] = client.Manager; + var calculationBasis = ""; + if (dic["浮动多头"].ToString() == "适用") + { + calculationBasis = fixLong?.FloatRateUnderlyingCode; + } + else if (dic["浮动空头"].ToString() == "适用") + { + calculationBasis = fixShort?.FloatRateUnderlyingCode; + } + else + { + calculationBasis = "不适用"; + } + + dic["计算基准"] = calculationBasis; + + double totalPosiQuantity = 0; + + foreach (var item in list) + { + var row = new JObject(); + + row["序号"] = ++count; + if (!string.IsNullOrWhiteSpace(item?.UnderlyingCode)) + { + var um = Context.GetTradeUnderlying(item?.UnderlyingCode); + row["标的名称"] = um.UnderlyingName; + row["标的代码"] = item?.UnderlyingCode; + decimal multiplier = um.IsBond() ? 100 : 1; + FormatToDict("期初价格", (double)((item?.PosiNetPrice * multiplier) ?? 0), row); + } + else + { + row["标的名称"] = ""; + row["标的代码"] = ""; + row["期初价格"] = ""; + } + FormatToDict("数量", (double)((item?.PosiQuantity) ?? 0), row); + totalPosiQuantity += (double)((item?.PosiQuantity) ?? 0); + FormatToDict("合约乘数", (double)((item?.ContractSize) ?? 0), row); + row["方向"] = item?.PositionType switch + { + 1 => "买入", + 2 => "卖出", + _ => "" + }; + table1.Add(row); + } + FormatToDict("名义本金", totalPosiQuantity, dic); + var underlyingCodes = swapFlowDeals.Select(r => r.UnderlyingCode).ToList(); + List underlyings = new List(); + if (underlyingCodes.Count() > 0) + { + underlyings = Context.GetUnderlyings(underlyingCodes); + } + foreach (var item in swapFlowDeals.OrderBy(o => o.UnderlyingCode).ThenBy(t => t.id)) + { + var row = new JObject(); + row["编号"] = ++count2; + row["标的代码"] = item.UnderlyingCode; + var um = underlyings.FirstOrDefault(x => x.UnderlyingCode == item.UnderlyingCode); + if (um != null) + { + row["标的名称"] = um.UnderlyingName; + if (um.IsBond()) + { + item.FullPrice *= ConsGlobal.bondShowPriceMultiple; + item.FullPriceFee *= ConsGlobal.bondShowPriceMultiple; + item.NetPrice *= ConsGlobal.bondShowPriceMultiple; + item.NetPriceFee *= ConsGlobal.bondShowPriceMultiple; + } + } + FormatToDict("成交收益率", (double)(item.Ytm), row); + FormatToDict("成交全价", (double)(item.FullPriceFee), row); + FormatToDict("成交数量", (double)(item.TradingQty), row); + row["成交方向"] = item?.BsType switch + { + 1 => "买入", + 2 => "卖出", + _ => "" + }; + row["交易日期"] = item.OccurDate.ToString("yyyy-MM-dd"); + table2.Add(row); + } + dic["table1"] = table1; + dic["flowtable"] = table2; + } + } +} \ No newline at end of file diff --git a/Plugins/YLErp.Plugins.ZheShang/DocumentGenerator/TradeSettleBillGenerator.cs b/Plugins/YLErp.Plugins.ZheShang/DocumentGenerator/TradeSettleBillGenerator.cs new file mode 100644 index 00000000..452169f2 --- /dev/null +++ b/Plugins/YLErp.Plugins.ZheShang/DocumentGenerator/TradeSettleBillGenerator.cs @@ -0,0 +1,203 @@ +using Newtonsoft.Json.Linq; +using Org.BouncyCastle.Utilities.Zlib; +using Qdp.Pricing.Base.Enums; +using Qdp.Pricing.Base.Interfaces; +using System.Data.Common; +using System.Diagnostics; +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.ShanXi.DocumentGenerator +{ + class TradeSettleBillGenerator : BaseSettleBillGenerator, ITradeSettleBillGenerator + { + protected override string GetContractNo(out string contractIndex) + { + var contractNo = Context.GenerateContractNo(out contractIndex); + return contractNo; + } + + protected override void PrepareViewData(Dictionary dic) + { + var client = Context.GetClient(); + var flowEvents = Context.GetFlowEvents(); + 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).OtcFormat(OtcFormatFlag.umprice); + 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; + row.PosiNotionalValue = PosiNotionalValue.ToString("0.00"); + row.PosiNetPrice = (posi.PosiGrossPrice * 100).OtcFormat(OtcFormatFlag.umprice); + //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 r = posi.PosiNetPrice == 0 ? 0 : PosiNotionalValue * posi.PosiNetPrice; + var FloatRate = r == 0 ? 0 : InterestAmount / r; + row.FloatRate = FloatRate.ToString("0.0000%"); + var PosiPnl = (-flowEventGroup.MarkClosePnl); + row.PosiPnl = PosiPnl.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(); + if (string.IsNullOrEmpty(client.SettleFileNumber)) + { + throw new ServiceException($"{client.Name}未设置定义文件编号"); + } + var flowEvents = Context.GetFlowEvents(); + var allFlowEvents = Context.GetAllFlowEvents(); + 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)) + { + throw new ServiceException($"{td.TradeNumber}未生成交易确认书"); + } + FormatToDict("平仓日期", eventDate,dic); + JArray table= new JArray(); + JArray table2 = new JArray(); + foreach ( var flowEvent in flowEvents ) + { + 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); + } + 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 == "定义文件型债券收益互换")) + { + templatePath = MosPathHelper.Combine(GlobalConfig.PluginFolder, "App_Docs\\结算单\\DMA结算单.docx"); + return templatePath; + } + templatePath = MosPathHelper.Combine(GlobalConfig.PluginFolder, "App_Docs\\结算单\\非DMA结算单.xlsx"); + return templatePath; + } + + protected override string GetOutputFileName(string contractNo, string contractIndex) + { + var trades = Context.Trades; + var client = Context.GetClient(); + var flowEvents = Context.GetFlowEvents(); + 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 == "定义文件型债券收益互换")) + { + FullName = $"{client.Name}-结算确认书-{valueDate}-交易平仓{countStr}"; + return $"{FullName}.docx"; + } + return $"{FullName}.xlsx"; + } + + } +} \ No newline at end of file diff --git a/Plugins/YLErp.Plugins.ZheShang/DocumentGenerator/TradeUnwindReportGenerator.cs b/Plugins/YLErp.Plugins.ZheShang/DocumentGenerator/TradeUnwindReportGenerator.cs new file mode 100644 index 00000000..d84d0f87 --- /dev/null +++ b/Plugins/YLErp.Plugins.ZheShang/DocumentGenerator/TradeUnwindReportGenerator.cs @@ -0,0 +1,135 @@ +using Newtonsoft.Json.Linq; +using YLErp.DBModels; +using YLErp.Plugins.TradeDocGenerator; +using YLErp.Plugins.TradeDocGenerator.Abstracts; + +namespace YLErp.Plugins.ShanXi.DocumentGenerator +{ + class TradeUnwindReportGenerator : BaseUnwindReportGenerator, ITradeUnwindReportGenerator + { + protected override string GetContractNo(out string contractIndex) + { + var contractNo = Context.GenerateContractNo(out contractIndex); + return contractNo; + } + + protected override void PrepareViewData(Dictionary dic) + { + var table1 = new JArray(); + var trade = Context.Trade; + var client = Context.GetClient(); + var valuetimelist = new List(); + var underlying = Context.GetTradeUnderlying(); + var variety = Context.GetUnderlyingVariety(); + var tradeCash = Context.GetTradeCash(); + 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 tradeCashs in Context.TradeCashes[item.id]) + { + var settlementprice = (trade.IsUsePremiumRate != null && trade.IsUsePremiumRate.Value ? tradeCashs.UnwindPricePercentRate.OtcFormatPercent() : tradeCashs.UnwindPrice.OtcFormatMoney()); + var row = new JObject(); + OtcTradeBase trades = tradelist.Find(O => O.id == tradeCashs.TradeId); + row["交易编号"] = trades.TradeNumber; + switch (item.BuySell) + { + case "买入": + if (trade.OpponentRole == null || trade.OpponentRole == "乙方") + { + row["买方"] = $"甲方"; + } + else + { + row["买方"] = $"乙方"; + } + break; + case "卖出": + if (trade.OpponentRole == null || trade.OpponentRole == "乙方") + { + row["买方"] = $"乙方"; + } + else + { + row["买方"] = $"甲方"; + } + break; + default: + 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["结算期权费"] = $"{Amountqrs.OtcFormatMoney()}"; + row["结算金额"] = $"{Amountqrs2.OtcFormatMoney()}"; + table1.Add(row); + valuetimelist.Add(tradeCashs.ValueDate); + } + } + dic["合同编号"] = Context.GenerateContractNo(out _); + dic["table1"] = table1; + dic["合同日期"] = $"{DateTime.Now.ToString("yyyy/MM/dd")}";//ValueDate + dic["了结日期1"] = $"{ valuetimelist.Min():yyyy/MM/dd}"; + dic["了结日期2"] = $"{ valuetimelist.Max():yyyy/MM/dd}"; + + #region 甲乙方信息判断 + + + 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["甲方"] = owner_Info != null ? owner_Info.FullName != null ? owner_Info.FullName : "" : ""; + dic["乙方"] = client != null ? client.Name : ""; + } + else + { + dic["甲方"] = client != null ? client.Name : ""; + dic["乙方"] = owner_Info != null ? owner_Info.FullName != null ? owner_Info.FullName : "" : ""; + } + + #endregion + } + + protected override string GetTemplateFilePath() + { + var templatePath = ""; + templatePath = Path.Combine(GlobalConfig.PluginFolder, "App_Docs\\结算单\\场外衍生品结算确认书.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 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"); + } + else + { + date = dts?.ToString("yyyyMMdd") + "-" + dte?.ToString("yyyyMMdd"); + } + 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.ZheShang/YLErp.Plugins.ZheShang.csproj b/Plugins/YLErp.Plugins.ZheShang/YLErp.Plugins.ZheShang.csproj new file mode 100644 index 00000000..b741a64b --- /dev/null +++ b/Plugins/YLErp.Plugins.ZheShang/YLErp.Plugins.ZheShang.csproj @@ -0,0 +1,35 @@ + + + + net6.0 + enable + enable + ..\build\ZheShang\ + + + + + + + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + + diff --git a/YLErpDAL/Modules/TradeModule/DocGenerateModule/ConfirmationGenerateContext.cs b/YLErpDAL/Modules/TradeModule/DocGenerateModule/ConfirmationGenerateContext.cs index 91b2f09b..e166578f 100644 --- a/YLErpDAL/Modules/TradeModule/DocGenerateModule/ConfirmationGenerateContext.cs +++ b/YLErpDAL/Modules/TradeModule/DocGenerateModule/ConfirmationGenerateContext.cs @@ -1274,6 +1274,9 @@ namespace YLErp.Modules.TradeModule.DocGenerateModule case CompanyEnum.山西固收: contractNo = GenerateShanXiGuShouContractNo(); break; + case CompanyEnum.浙商: + contractNo = GenerateZheShangContractNo(); + break; default: throw new ContextMarshalException("未实现"); } @@ -1311,6 +1314,18 @@ namespace YLErp.Modules.TradeModule.DocGenerateModule return contractNo; } /// + /// 浙商交易确认书编号 + /// + /// + private string GenerateZheShangContractNo() + { + if (_contractType != ContractTypeEnum.Trade) + { + return UniqueTimeId.GetStr(); + } + return Trade.TradeNumber; + } + /// /// 生成国贸确认书编号 /// /// diff --git a/YLErpWeb/appsettings.local.json b/YLErpWeb/appsettings.local.json index ba7e8acd..bc113b43 100644 --- a/YLErpWeb/appsettings.local.json +++ b/YLErpWeb/appsettings.local.json @@ -16,7 +16,7 @@ "AppSettings": { "VirtualPathRoot": "", "UseRightAligned": "", - "PluginFolder": "D:\\gitCode\\shanzheng-trs\\Plugins\\YLErp.Plugins.ShanXi\\obj\\Debug\\net6.0" + "PluginFolder": "D:\\Code\\ZS_GitlabYilianCode\\Plugins\\build\\ZheShang\\Debug\\net6.0" }, "LibreOffice": { "ExePath": "", diff --git a/YLerpbase.sln b/YLerpbase.sln index 163c14d6..8c855d15 100644 --- a/YLerpbase.sln +++ b/YLerpbase.sln @@ -35,6 +35,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "YLErp.Jobs", "Framework\YLE EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "YLErp.Cache", "Framework\YLErp.Cache\YLErp.Cache.csproj", "{5665673C-1157-444F-AABC-2A873D8E4703}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "YLErp.Plugins.ZheShang", "Plugins\YLErp.Plugins.ZheShang\YLErp.Plugins.ZheShang.csproj", "{C94D2467-B0E8-48CA-B60D-CD660B73AE90}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -86,6 +88,10 @@ Global {5665673C-1157-444F-AABC-2A873D8E4703}.Debug|Any CPU.Build.0 = Debug|Any CPU {5665673C-1157-444F-AABC-2A873D8E4703}.Release|Any CPU.ActiveCfg = Release|Any CPU {5665673C-1157-444F-AABC-2A873D8E4703}.Release|Any CPU.Build.0 = Release|Any CPU + {C94D2467-B0E8-48CA-B60D-CD660B73AE90}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C94D2467-B0E8-48CA-B60D-CD660B73AE90}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C94D2467-B0E8-48CA-B60D-CD660B73AE90}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C94D2467-B0E8-48CA-B60D-CD660B73AE90}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -100,6 +106,7 @@ Global {1C55DA41-0DFE-49C1-9811-F4BAEDF7EEE6} = {F315B5D3-F4FE-43E5-AF22-AF92978A71BE} {DB3402A2-7121-4F5A-9F0F-A258EC582370} = {F315B5D3-F4FE-43E5-AF22-AF92978A71BE} {5665673C-1157-444F-AABC-2A873D8E4703} = {F315B5D3-F4FE-43E5-AF22-AF92978A71BE} + {C94D2467-B0E8-48CA-B60D-CD660B73AE90} = {5981434D-792E-4528-AFC8-7EB8AFD9F80C} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {28638B67-A6D3-4355-8ADB-EACEE98510B0}