TRS-ZS-183 一个客户一天所有开仓的多头交易都放到一个交易确认书里

This commit is contained in:
锦麟 王
2025-04-22 09:45:21 +08:00
parent 4b9bcfb2dc
commit 5ba29de3ed
21 changed files with 1176 additions and 393 deletions
@@ -227,12 +227,12 @@ namespace YLErp.Plugins.TradeDocGenerator
protected void FormatToDict(string key, DateTime? value, JObject dict)
{
dict[key] = value?.ToString("yyyy年MM月dd日");
dict[key.Insert(key.Length - 2, "N")] = value?.ToString("yyyyMMdd");
dict[key.Insert(key.Length - 2, "/")] = value?.ToString("yyyy/MM/dd");
dict[key.Insert(key.Length - 2, "-")] = value?.ToString("yyyy-MM-dd");
dict[key.Insert(key.Length - 2, "年")] = value?.ToString("yyyy");
dict[key.Insert(key.Length - 2, "月")] = value?.ToString("MM");
dict[key.Insert(key.Length - 2, "日")] = value?.ToString("dd");
dict[key.Insert(key.Length, "N")] = value?.ToString("yyyyMMdd");
dict[key.Insert(key.Length, "/")] = value?.ToString("yyyy/MM/dd");
dict[key.Insert(key.Length, "-")] = value?.ToString("yyyy-MM-dd");
dict[key.Insert(key.Length, "年")] = value?.ToString("yyyy");
dict[key.Insert(key.Length, "月")] = value?.ToString("MM");
dict[key.Insert(key.Length, "日")] = value?.ToString("dd");
}
/// <summary>
@@ -244,12 +244,12 @@ namespace YLErp.Plugins.TradeDocGenerator
protected void FormatToDict(string key, DateTime value, Dictionary<string, string> dict)
{
dict[key] = value.ToString("yyyy年MM月dd日");
dict[key.Insert(key.Length - 2, "N")] = value.ToString("yyyyMMdd");
dict[key.Insert(key.Length - 2, "/")] = value.ToString("yyyy/MM/dd");
dict[key.Insert(key.Length - 2, "-")] = value.ToString("yyyy-MM-dd");
dict[key.Insert(key.Length - 2, "年")] = value.ToString("yyyy");
dict[key.Insert(key.Length - 2, "月")] = value.ToString("MM");
dict[key.Insert(key.Length - 2, "日")] = value.ToString("dd");
dict[key.Insert(key.Length, "N")] = value.ToString("yyyyMMdd");
dict[key.Insert(key.Length, "/")] = value.ToString("yyyy/MM/dd");
dict[key.Insert(key.Length, "-")] = value.ToString("yyyy-MM-dd");
dict[key.Insert(key.Length, "年")] = value.ToString("yyyy");
dict[key.Insert(key.Length, "月")] = value.ToString("MM");
dict[key.Insert(key.Length, "日")] = value.ToString("dd");
}
/// <summary>
@@ -261,8 +261,8 @@ namespace YLErp.Plugins.TradeDocGenerator
protected void FormatToDict(string key, int value, JObject dict)
{
dict[key] = value.ToString("0");
dict[key.Insert(key.Length - 2, "A")] = Math.Abs(value).ToString("0");
dict[key.Insert(key.Length - 2, "大写")] = Context.CmycurD(Math.Abs(value));
dict[key.Insert(key.Length, "A")] = Math.Abs(value).ToString("0");
dict[key.Insert(key.Length, "大写")] = Context.CmycurD(Math.Abs(value));
}
/// <summary>
@@ -275,28 +275,28 @@ namespace YLErp.Plugins.TradeDocGenerator
{
value = value == -0 ? 0 : value;
dict[key] = value?.ToString("0.00");
dict[key.Insert(key.Length - 2, "2")] = value?.ToString("0.00");
dict[key.Insert(key.Length - 2, "3")] = value?.ToString("0.000");
dict[key.Insert(key.Length - 2, "4")] = value?.ToString("0.0000");
dict[key.Insert(key.Length - 2, "5")] = value?.ToString("0.00000");
dict[key.Insert(key.Length - 2, "6")] = value?.ToString("0.000000");
dict[key.Insert(key.Length - 2, "A")] = value != null ? Math.Abs(value.Value).ToString("0") : "";
dict[key.Insert(key.Length - 2, "A2")] = value != null ? Math.Abs(value.Value).ToString("0.00") : "";
dict[key.Insert(key.Length - 2, "A3")] = value != null ? Math.Abs(value.Value).ToString("0.000") : "";
dict[key.Insert(key.Length - 2, "A4")] = value != null ? Math.Abs(value.Value).ToString("0.0000") : "";
dict[key.Insert(key.Length - 2, "A5")] = value != null ? Math.Abs(value.Value).ToString("0.00000") : "";
dict[key.Insert(key.Length - 2, "A6")] = value != null ? Math.Abs(value.Value).ToString("0.000000") : "";
dict[key.Insert(key.Length - 2, "2?")] = value?.ToString("0.##");
dict[key.Insert(key.Length - 2, "3?")] = value?.ToString("0.###");
dict[key.Insert(key.Length - 2, "4?")] = value?.ToString("0.####");
dict[key.Insert(key.Length - 2, "5?")] = value?.ToString("0.#####");
dict[key.Insert(key.Length - 2, "6?")] = value?.ToString("0.######");
dict[key.Insert(key.Length - 2, "A2?")] = value != null ? Math.Abs(value.Value).ToString("0.##") : "";
dict[key.Insert(key.Length - 2, "A3?")] = value != null ? Math.Abs(value.Value).ToString("0.###") : "";
dict[key.Insert(key.Length - 2, "A4?")] = value != null ? Math.Abs(value.Value).ToString("0.####") : "";
dict[key.Insert(key.Length - 2, "A5?")] = value != null ? Math.Abs(value.Value).ToString("0.#####") : "";
dict[key.Insert(key.Length - 2, "A6?")] = value != null ? Math.Abs(value.Value).ToString("0.######") : "";
dict[key.Insert(key.Length - 2, "大写")] = value != null ? Context.CmycurD(Math.Abs(value.Value)) : "";
dict[key.Insert(key.Length, "2")] = value?.ToString("0.00");
dict[key.Insert(key.Length, "3")] = value?.ToString("0.000");
dict[key.Insert(key.Length, "4")] = value?.ToString("0.0000");
dict[key.Insert(key.Length, "5")] = value?.ToString("0.00000");
dict[key.Insert(key.Length, "6")] = value?.ToString("0.000000");
dict[key.Insert(key.Length, "A")] = value != null ? Math.Abs(value.Value).ToString("0") : "";
dict[key.Insert(key.Length, "A2")] = value != null ? Math.Abs(value.Value).ToString("0.00") : "";
dict[key.Insert(key.Length, "A3")] = value != null ? Math.Abs(value.Value).ToString("0.000") : "";
dict[key.Insert(key.Length, "A4")] = value != null ? Math.Abs(value.Value).ToString("0.0000") : "";
dict[key.Insert(key.Length, "A5")] = value != null ? Math.Abs(value.Value).ToString("0.00000") : "";
dict[key.Insert(key.Length, "A6")] = value != null ? Math.Abs(value.Value).ToString("0.000000") : "";
dict[key.Insert(key.Length, "2?")] = value?.ToString("0.##");
dict[key.Insert(key.Length, "3?")] = value?.ToString("0.###");
dict[key.Insert(key.Length, "4?")] = value?.ToString("0.####");
dict[key.Insert(key.Length, "5?")] = value?.ToString("0.#####");
dict[key.Insert(key.Length, "6?")] = value?.ToString("0.######");
dict[key.Insert(key.Length, "A2?")] = value != null ? Math.Abs(value.Value).ToString("0.##") : "";
dict[key.Insert(key.Length, "A3?")] = value != null ? Math.Abs(value.Value).ToString("0.###") : "";
dict[key.Insert(key.Length, "A4?")] = value != null ? Math.Abs(value.Value).ToString("0.####") : "";
dict[key.Insert(key.Length, "A5?")] = value != null ? Math.Abs(value.Value).ToString("0.#####") : "";
dict[key.Insert(key.Length, "A6?")] = value != null ? Math.Abs(value.Value).ToString("0.######") : "";
dict[key.Insert(key.Length, "大写")] = value != null ? Context.CmycurD(Math.Abs(value.Value)) : "";
}
/// <summary>
@@ -309,28 +309,28 @@ namespace YLErp.Plugins.TradeDocGenerator
{
value = value == -0 ? 0 : value;
dict[key] = value.ToString("0.00");
dict[key.Insert(key.Length - 2, "2")] = value.ToString("0.00");
dict[key.Insert(key.Length - 2, "3")] = value.ToString("0.000");
dict[key.Insert(key.Length - 2, "4")] = value.ToString("0.0000");
dict[key.Insert(key.Length - 2, "5")] = value.ToString("0.00000");
dict[key.Insert(key.Length - 2, "6")] = value.ToString("0.000000");
dict[key.Insert(key.Length - 2, "A")] = Math.Abs(value).ToString("0");
dict[key.Insert(key.Length - 2, "A2")] = Math.Abs(value).ToString("0.00");
dict[key.Insert(key.Length - 2, "A3")] = Math.Abs(value).ToString("0.000");
dict[key.Insert(key.Length - 2, "A4")] = Math.Abs(value).ToString("0.0000");
dict[key.Insert(key.Length - 2, "A5")] = Math.Abs(value).ToString("0.00000");
dict[key.Insert(key.Length - 2, "A6")] = Math.Abs(value).ToString("0.000000");
dict[key.Insert(key.Length - 2, "2?")] = value.ToString("0.##");
dict[key.Insert(key.Length - 2, "3?")] = value.ToString("0.###");
dict[key.Insert(key.Length - 2, "4?")] = value.ToString("0.####");
dict[key.Insert(key.Length - 2, "5?")] = value.ToString("0.#####");
dict[key.Insert(key.Length - 2, "6?")] = value.ToString("0.######");
dict[key.Insert(key.Length - 2, "A2?")] = Math.Abs(value).ToString("0.##");
dict[key.Insert(key.Length - 2, "A3?")] = Math.Abs(value).ToString("0.###");
dict[key.Insert(key.Length - 2, "A4?")] = Math.Abs(value).ToString("0.####");
dict[key.Insert(key.Length - 2, "A5?")] = Math.Abs(value).ToString("0.#####");
dict[key.Insert(key.Length - 2, "A6?")] = Math.Abs(value).ToString("0.######");
dict[key.Insert(key.Length - 2, "大写")] = Context.CmycurD(Math.Abs(value));
dict[key.Insert(key.Length, "2")] = value.ToString("0.00");
dict[key.Insert(key.Length, "3")] = value.ToString("0.000");
dict[key.Insert(key.Length, "4")] = value.ToString("0.0000");
dict[key.Insert(key.Length, "5")] = value.ToString("0.00000");
dict[key.Insert(key.Length, "6")] = value.ToString("0.000000");
dict[key.Insert(key.Length, "A")] = Math.Abs(value).ToString("0");
dict[key.Insert(key.Length, "A2")] = Math.Abs(value).ToString("0.00");
dict[key.Insert(key.Length, "A3")] = Math.Abs(value).ToString("0.000");
dict[key.Insert(key.Length, "A4")] = Math.Abs(value).ToString("0.0000");
dict[key.Insert(key.Length, "A5")] = Math.Abs(value).ToString("0.00000");
dict[key.Insert(key.Length, "A6")] = Math.Abs(value).ToString("0.000000");
dict[key.Insert(key.Length, "2?")] = value.ToString("0.##");
dict[key.Insert(key.Length, "3?")] = value.ToString("0.###");
dict[key.Insert(key.Length, "4?")] = value.ToString("0.####");
dict[key.Insert(key.Length, "5?")] = value.ToString("0.#####");
dict[key.Insert(key.Length, "6?")] = value.ToString("0.######");
dict[key.Insert(key.Length, "A2?")] = Math.Abs(value).ToString("0.##");
dict[key.Insert(key.Length, "A3?")] = Math.Abs(value).ToString("0.###");
dict[key.Insert(key.Length, "A4?")] = Math.Abs(value).ToString("0.####");
dict[key.Insert(key.Length, "A5?")] = Math.Abs(value).ToString("0.#####");
dict[key.Insert(key.Length, "A6?")] = Math.Abs(value).ToString("0.######");
dict[key.Insert(key.Length, "大写")] = Context.CmycurD(Math.Abs(value));
}
protected void FormatToDict(string v, string Date, Dictionary<string, string> dic)
@@ -1,15 +1,18 @@
using Newtonsoft.Json.Linq;
using Microsoft.VisualBasic;
using Newtonsoft.Json.Linq;
using NPOI.SS.Formula.Functions;
using System.Text.RegularExpressions;
using YLErp.Core.Helpers;
using YLErp.DBModels;
using YLErp.DBModels.Consts;
using YLErp.DBModels.Enums;
using YLErp.Enums;
using YLErp.Plugins.TradeDocGenerator;
using YLErp.Plugins.TradeDocGenerator.Abstracts;
namespace YLErp.Plugins.ShanXi.DocumentGenerator
{
internal class TradeConfirmationGenerator : BaseConfirmationGenerator, ITradeConfirmationGenerator
internal class TradeConfirmationGenerator : BaseConfirmationGenerator_Batch, ITradeConfirmationGenerator
{
public TradeConfirmationGenerator()
: base(ContractTypeEnum.Trade)
@@ -21,23 +24,29 @@ namespace YLErp.Plugins.ShanXi.DocumentGenerator
{
string templatePath = null;
var trade = Context.Trade;
if (trade.TradeType == "收益互换" && trade.StructureType != null)
if (trade.TradeType == "收益互换") //&& trade.StructureType != null)
{
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;
}
}
//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\\交易确认书\\浙商证券利率债收益互换合约交易确认书模版.docx");
//}
}
else
{
@@ -78,87 +87,159 @@ namespace YLErp.Plugins.ShanXi.DocumentGenerator
/// <param name="dic"></param>
public void SetSwapData(Dictionary<string, JToken> dic)
{
SetSingleSwap(dic);
var trade = Context.Trade;
SetSingleSwap(dic);
}
private void SetSingleSwap(Dictionary<string, JToken> 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["交易编号"] = GetContractNo(out string contractIndex);
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;
var count = 0;
FormatToDict("期初标的交割全价", (double)((swapPosition?.PosiGrossPrice) ?? 0) * 100, dic);
FormatToDict("期初标的交割净价", (double)((swapPosition?.PosiNetNoFeePrice) ?? 0) * 100, dic);
if (string.IsNullOrWhiteSpace(interestMargin?.FloatRateUnderlyingCode))
var trades = Context.Trades;
var totalPosiQuantity = 0.0;
foreach (var trade in trades)
{
dic["利率类型"] = "固定利率";
dic["利差"] = "";
dic["固定利率"] = ((interestMargin?.InterestRateDefault) ?? 0) * 100;
dic["参考利率"] = "";
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;
if (count == 0)
{
dic["名义本金".Insert("名义本金".Length, "2?")] = trade.StockEqvNotionalReal.ToString("0.##");
dic["成交日期"] = trade.TradeDate?.ToString("yyyy年M月d日");
dic["开始日期"] = trade.StartDate?.ToString("yyyy年M月d日");
dic["到期日期"] = trade.ExerciseDate?.ToString("yyyy年M月d日");
bool posiLong = swapPosition?.PositionType == (int)PositionTypeFlag.Short ? false : true;
var interestRate = interestMargin?.InterestRateDefault * 100 ?? 0;
var basicFee = trade.StockEqvNotionalReal == 0 ? 0 : ((double)((swapPosition?.PosiTradingFeePending) ?? 0) / trade.StockEqvNotionalReal) * 100;
dic["基本费率"] = (basicFee * 2).ToString("f4");
dic["交易费用"] = (double)((swapPosition?.PosiTradingFeePending * 2) ?? 0);
dic["多头约定利率"] = "不适用";
dic["空头约定利率"] = "不适用";
if (posiLong)
{
dic["支付方"] = "乙方支付";
dic["接收方"] = "甲方收取";
}
else
{
dic["支付方"] = "甲方支付";
dic["接收方"] = "乙方收取";
}
if (string.IsNullOrEmpty(interestMargin?.FloatRateUnderlyingCode))
{
dic["利率类型"] = "固定利率";
dic["利差"] = "";
dic["固定利率"] = ((interestMargin?.InterestRateDefault) ?? 0) * 100;
dic["参考利率"] = "";
dic["重置频率"] = "";
if (posiLong)
{
dic["多头约定利率"] = ((double)interestRate).ToString("0.####") + "%";
}
else
{
dic["空头约定利率"] = ((double)interestRate).ToString("0.####") + "%";
}
}
else
{
dic["利率类型"] = "浮动利率";
dic["利差"] = ((interestMargin?.InterestRateDefault) ?? 0) * 10000;
dic["利差%"] = ((interestMargin?.InterestRateDefault) ?? 0) * 100;
dic["参考利率"] = interestMargin?.FloatRateUnderlyingCode;
dic["固定利率"] = "";
dic["重置频率"] = interestMargin?.interest_rest_days;
}
dic["初始预付金支付日"] = interestMargin?.HappenDate == null ? "" : interestMargin?.HappenDate?.ToString("【yyyy】年【M】月【d】日");
dic["管理人名称"] = client.Manager;
var calculationBasis = interestMargin?.FloatRateUnderlyingCode;
if (!string.IsNullOrEmpty(calculationBasis))
{
calculationBasis += interestRate > 0 ? " + " + ((double)interestRate).ToString("0.####") + "%" : ((double)interestRate).ToString("0.####") + "%";
}
else
{
calculationBasis = ((double)interestRate).ToString("0.####") + "%";
}
dic["计算基准"] = calculationBasis;
dic["初始保障金率"] = ((clientMarginRate?.InitMarginRate ?? 0) * 100).ToString("0.####") + "%";
dic["维持保障金率"] = ((clientMarginRate?.MaintenanceRate ?? 0) * 100).ToString("0.####") + "%";
}
var row = new JObject();
row["序号"] = ++count;
FormatToDict("名义本金", trade.StockEqvNotionalReal, row);
row["成交日期"] = trade.TradeDate?.ToString("【yyyy】年【M】月【d】日");
row["开始日期"] = trade.StartDate?.ToString("【yyyy】年【M】月【d】日");
row["到期日期"] = trade.ExerciseDate?.ToString("【yyyy】年【M】月【d】日");
row["成交日期2"] = trade.TradeDate?.ToString("【yyyy】年【M】月【d】日");
row["户名"] = bank?.ClientName;
row["银行账号"] = bank?.Card;
row["开户行"] = bank?.Bank;
row["大额行号"] = bank?.Payment;
FormatToDict("期初标的交割全价", (double)((swapPosition?.PosiGrossPrice) ?? 0) * 100, row);
FormatToDict("期初标的交割净价", (double)((swapPosition?.PosiNetNoFeePrice) ?? 0) * 100, row);
//row["利差"] = ((interestMargin?.InterestRateDefault) ?? 0) * 100;
//var basicFee = trade.StockEqvNotionalReal == 0 ? 0 : ((double)((swapPosition?.PosiTradingFeePending) ?? 0) / trade.StockEqvNotionalReal) * 100;
//row["基本费率"] = (basicFee * 2).ToString("f4");
var initialMarginSum = initialMarginQuery.Sum(x =>
x.InterestDirection == 2 ? x.InterestPrincipalFix * -1 : x.InterestPrincipalFix);
FormatToDict("交易费用", (double)((swapPosition?.PosiTradingFeePending * 2) ?? 0), row);
row["交易费率"] = row["基本费率"];
FormatToDict("期初预付金", (double)initialMarginSum, row);
row["期初预付金利率"] = ((initialMarginQuery.FirstOrDefault()?.InterestRateDefault) ?? 0) * 100;
row["追加预付金返息率"] = ((clientMarginRate?.AddToMarginRebateRate) ?? 0) * 100;
if (!string.IsNullOrEmpty(underlyingCode))
{
var um = Context.GetTradeUnderlying(underlyingCode);
row["标的代码"] = um.UnderlyingCode;
row["标的名称"] = um.UnderlyingName;
var bond = JsonHelper.Deserialize<UnderlyingBond>(um.ExJson) ??
new UnderlyingBond();
row["标的发行人"] = bond.UnderlyingIssuer;
decimal multiplier = um.IsBond() ? 100 : 1;
FormatToDict("期初价格", (double)((swapPosition?.PosiGrossPrice * multiplier) ?? 0), row);
}
else
{
row["标的名称"] = "";
row["标的代码"] = "";
row["期初价格"] = "";
}
FormatToDict("数量", (double)((swapPosition?.PosiQuantity) ?? 0), row);
totalPosiQuantity += (double)((swapPosition?.PosiQuantity) ?? 0);
FormatToDict("合约乘数", (double)((swapPosition?.ContractSize) ?? 0), row);
row["方向"] = swapPosition?.PositionType switch
{
1 => "买入",
2 => "卖出",
_ => ""
};
table1.Add(row);
}
else
{
dic["利率类型"] = "浮动利率";
dic["利差"] = ((interestMargin?.InterestRateDefault) ?? 0) * 10000;
dic["参考利率"] = interestMargin?.FloatRateUnderlyingCode;
dic["固定利率"] = "";
}
if (initialMarginQuery.Any())
{
dic["初始预付金支付日"] = initialMarginQuery.FirstOrDefault().HappenDate?.ToString("【yyyy】年【M】月【d】日");
}
else
{
dic["初始预付金支付日"] = "";
}
FormatToDict("标的期初全价", trade.StockEqvNotionalReal * (double)((swapPosition?.PosiGrossPrice) ?? 0), dic);
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<UnderlyingBond>(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)
clientduties = clientduties.Where(x => x.ContactTypeId.Contains("3")).OrderBy(o => o.id).ToList();//交易确认书邮件接收人
if (clientduties.Count > 0)
{
var clientduty= clientduties.First();
var clientduty = clientduties.First();
var row = new JObject();
row["姓名"] = clientduty.ContactName;
row["身份证号"] = clientduty.IdCardNo;
@@ -168,9 +249,9 @@ namespace YLErp.Plugins.ShanXi.DocumentGenerator
table2.Add(row);
}
dic["table1"] = table1;
dic["table2"] = table2;
}
}
}
@@ -18,6 +18,12 @@
<None Update="App_Docs\交易确认书\客户空头交易确认书模板.docx">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="App_Docs\交易确认书\收益互换交易确认书(DMA)模板.docx">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="App_Docs\交易确认书\浙商证券利率债收益互换合约交易确认书模版.docx">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="App_Docs\结算单\DMA结算单.docx">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
+8 -3
View File
@@ -8,9 +8,14 @@ namespace YLErp.Model
{
public class SwapTradeSendEmailReq
{
public SwapTradeSendEmailReq() {
tradeIds = new List<int>();
//public SwapTradeSendEmailReq() {
// tradeIds = new List<int>();
//}
//public List<int> tradeIds;
public SwapTradeSendEmailReq()
{
contractCodes = new List<string>();
}
public List<int> tradeIds;
public List<string> contractCodes;
}
}
+1 -1
View File
@@ -8,7 +8,7 @@ namespace YLErp.Model
{
public class SwapTradeSendEmailResp
{
public int tradeId { get; set; }
public string contractCode { get; set; }
public string send_email_result { get; set; }
}
}
+2
View File
@@ -26,6 +26,8 @@
/// 确认书编号
/// </summary>
public string ContractCode { get; set; }
public List<string> ContractCodes { get; set; } = null;
/// <summary>
/// 交易资金Id
/// </summary>
@@ -169,36 +169,46 @@ namespace YLErp.Modules.SwapModule
/// </summary>
/// <param name="tradeId"></param>
/// <returns></returns>
public string SendConfirmEamil(int tradeId)
public string SendConfirmEamil(string contractCode)
{
var tradeContract = DbContext.trade_contract_r.Where(x => x.IsValid && x.TradeId == tradeId && x.Type == ContractTypeEnum.Trade).FirstOrDefault();
if (tradeContract == null)
//var tradeContract = DbContext.trade_contract_r.Where(x => x.IsValid && x.TradeId == tradeId && x.Type == ContractTypeEnum.Trade).FirstOrDefault();
//if (tradeContract == null)
//{
// return "";
//}
var contracts = DbContext.trade_contract_r.Where(o => o.ContractCode == contractCode && o.Type == ContractTypeEnum.Trade && o.IsValid).ToArray();
foreach (var tradeContract in contracts)
{
return "";
tradeContract.send_email_result = "发送中";
DbContext.SaveChanges();
}
tradeContract.send_email_result = "发送中";
var sendResult = SendEmail(contractCode);
foreach (var tradeContract in contracts)
{
if (string.IsNullOrEmpty(sendResult))
{
tradeContract.send_email_result = "已发送";
}
else
{
tradeContract.send_email_result = "发送失败:" + sendResult;
}
}
DbContext.SaveChanges();
var sendResult = SendEmail(tradeId);
if (string.IsNullOrEmpty(sendResult))
{
tradeContract.send_email_result = "已发送";
}
else
{
tradeContract.send_email_result = "发送失败:" + sendResult;
}
DbContext.SaveChanges();
return tradeContract.send_email_result;
return string.IsNullOrEmpty(sendResult) ? "已发送" : "发送失败:" + sendResult;
}
/// <summary>
/// 发送邮件
/// </summary>
/// <returns></returns>
private string SendEmail(int tradeId)
private string SendEmail(string contractCode)
{
var baseUrl = Environment.GetEnvironmentVariable("BondOmsInterface_BaseUrl");
var sendEmailPUrl = "/swap/email/confirm/send?tradeId=" + tradeId;
//换成contractCode
var sendEmailPUrl = "/swap/email/confirm/send?contractCode=" + contractCode;
if (!string.IsNullOrEmpty(baseUrl))
{
var httpHelper = new HttpHelper(baseUrl, null);
@@ -209,7 +219,7 @@ namespace YLErp.Modules.SwapModule
}
else
{
LogFactory.GetLogger().Error("发送邮件失败:tradeId=" + tradeId, new Exception(result?.message));
LogFactory.GetLogger().Error("发送邮件失败:contractCode=" + contractCode, new Exception(result?.message));
return result?.message ?? "发送邮件失败";
}
}
@@ -1,8 +1,10 @@
using BaseOUDAL;
using System.Collections.Concurrent;
using System.Drawing.Printing;
using YLErp.Configuration;
using YLErp.DBModels.Consts;
using YLErp.Model;
using YLErp.Model.Enum;
using YLErp.Models;
using YLErp.Modules.TradeDalModule;
using YLErp.Modules.TradeModule.DocGenerateModule;
@@ -207,187 +209,34 @@ namespace YLErp.Modules.TradeModule.DealModule
List<TradeDocGenerateResult> results = new List<TradeDocGenerateResult>();
List<string> error = new List<string>();
List<string> file = new List<string>();
if (PS.Config.Is国泰君安 || PS.Config.Is厦门象屿)
{
var Tradelist = new TradeDalService(this).GetTradeOrEodTradeOfTidAPid(tradeIds, SystemValueDate, false, false);
using (var basedb = new ErpBaseContext())
{
if (Tradelist.Any(O => O.IsGroup > 0))
{
int count = Tradelist.Where(O => O.IsGroup != 2).GroupBy(O => O.IsGroup).Count();
if (count > 1)
{
throw new ServiceException("不应勾选多个非黑盒标的的交易");
}
var list = Tradelist.Where(x => x.TradeType == "结构化交易");
var group = list.GroupBy(O => new { O.ClientId, O.StructureType }).ToDictionary(K => K.Key, V => V.Select(O => O.id).ToList());
foreach (var item in group)
{
if (item.Key.StructureType == "折价")
{
var list2 = list.Where(x => item.Value.Contains(x.id) && x.TradeType == "结构化交易").ToList();
list2.ForEach(x =>
{
var options = x.Propertys?.Where(o => o.name == "看涨看跌").ToList();
if (options != null && options.Any())
{
x.ExtendOptionTypeInfo = JsonHelper.Serialize(options);
}
else
{
throw new ServiceException("看涨看跌不能为空:" + x.TradeNumber);
}
});
var group2 = list2.GroupBy(O => O.ExtendOptionTypeInfo).ToDictionary(K => K.Key, V => V.Select(O => O.id).ToList());
foreach (var item2 in group2)
{
groupGenerateHandle_Date(item2.Value, docType, startDate, endDate, results, error, file);
if (error.Any()) break;
}
}
else
{
groupGenerateHandle_Date(item.Value, docType, startDate, endDate, results, error, file);
if (error.Any()) break;
}
}
var swapList = Tradelist.Where(x => x.TradeType == "收益互换" && x.ParentTradeId == 0);
foreach (var item in swapList)
{
groupGenerateHandle_Date(new List<int> { item.id }, docType, startDate, endDate, results, error, file);
}
}
}
if (results.Count == 0)
{
var structTradeQuery = new TradeDalService(this).GetTradeOrEodTradeOfTidASid(tradeIds, SystemValueDate).Where(c => c.TradeType != "结构化交易");
List<string> instrumentTypeArr = new List<string>() { ConsGlobal.InstrumentType.Stock, ConsGlobal.InstrumentType.StockIndex, ConsGlobal.InstrumentType.StockIF };
DataCacheProvider.GetUnderlyingDataSource().AsQueryable();
if (structTradeQuery.Any(O => instrumentTypeArr.Contains(getUnderlyingInstrumentType(O.UnderlyingId)) || O.TradeType == "雪球期权"))
{
//暂时将所有子交易都作为判断依据,等拿到模板后再根据模板做调整更改;
//目前是否为权益类的判断条件只是是否是股票,没有考虑IC IF等品种;
int count = structTradeQuery.GroupBy(O => new { UnderlyingInstrumentType = (instrumentTypeArr.Contains(getUnderlyingInstrumentType(O.UnderlyingId)) || O.TradeType == "雪球期权") ? 1 : 0 }).Count();
if (count > 1)
{
throw new ServiceException("不应勾选多个非股票(含股指期货)标的的交易");
}
var group = structTradeQuery.GroupBy(O => new { O.ClientId, O.TradeType }).ToDictionary(K => K.Key, V => V.Select(O => O.id).ToList());
foreach (var item in group)
{
if (item.Key.TradeType == "雪球期权")
{
if (structTradeQuery.Any(O => !instrumentTypeArr.Contains(getUnderlyingInstrumentType(O.UnderlyingId))))
{
var group2 = DbContext.trade.Where(c => item.Value.Contains(c.id)).AsEnumerable().GroupBy(m => m.OptionType).ToDictionary(K => K.Key, V => V.Select(O => O.id).ToList());
foreach (var item2 in group2)
{
groupGenerateHandle_Date(item2.Value, docType, startDate, endDate, results, error, file);
if (error.Any()) break;
}
}
else
{
var group2 = DbContext.trade_snowball.Where(c => item.Value.Contains(c.TradeId)).AsEnumerable().GroupBy(m => m.IsFixedCoupon).ToDictionary(K => K.Key, V => V.Select(O => O.TradeId).ToList());
foreach (var item2 in group2)
{
if (item2.Key)
{
groupGenerateHandle_Date(item2.Value, docType, startDate, endDate, results, error, file);
if (error.Any()) break;
}
else
{
var group3 = DbContext.trade.Where(c => item2.Value.Contains(c.id)).AsEnumerable().GroupBy(m => m.OptionType).ToDictionary(K => K.Key, V => V.Select(O => O.id).ToList());
foreach (var item3 in group3)
{
groupGenerateHandle_Date(item3.Value, docType, startDate, endDate, results, error, file);
if (error.Any()) break;
}
}
}
}
}
else
{
groupGenerateHandle_Date(item.Value, docType, startDate, endDate, results, error, file);
if (error.Any()) break;
}
}
}
}
}
else if (PS.Config.Is润和)
if (PS.Config.Company == CompanyEnum.)
{
var TradeQuery = new TradeDalService(this).GetTradeOrEodTradeOfTidASid(tradeIds, SystemValueDate).Where(c => (c.TradeType != "结构化交易" || c.IsGroup == 1) && tradeIds.Contains(c.id));
if (TradeQuery.Any())
{
var group = TradeQuery.GroupBy(O => new { O.ClientId, O.TradeDate }).ToDictionary(K => K.Key, V => V.Select(O => O.id).ToList());
foreach (var item in group)
var Ids = TradeQuery.Select(o => o.id).Distinct().ToArray();
var swapPositions = DbContext.swap_position.Where(s => Ids.Contains(s.SwapTradeId) && s.IsInitial && s.PositionType > 0 && !s.Invalid)
.Distinct().ToList();
foreach (var item in TradeQuery)
{
var group2 = DbContext.trade.Where(c => item.Value.Contains(c.id) && c.TradeType == "远期").Select(O => O.id).ToList();
if (group2.Any())
{
groupGenerateHandle(group2, docType, startDate, endDate, results, error, file);
if (error.Any()) break;
}
var group4 = DbContext.trade.Where(c => item.Value.Contains(c.id) && c.TradeType == "亚式期权").Select(O => O.id).ToList();
if (group4.Any())
{
groupGenerateHandle(group4, docType, startDate, endDate, results, error, file);
if (error.Any()) break;
}
var group3 = DbContext.trade.Where(c => item.Value.Contains(c.id) && c.TradeType != "远期" && c.TradeType != "亚式期权").Select(O => O.id).ToList();
if (group3.Any())
{
groupGenerateHandle(group3, docType, startDate, endDate, results, error, file);
if (error.Any()) break;
}
item.swap_positions.Add(swapPositions.FirstOrDefault(o => o.SwapTradeId == item.id));
}
}
}
else if (PS.Config.Is东吴)
{
var TradeQuery = new TradeDalService(this).GetTradeOrEodTradeOfTidASid(tradeIds, SystemValueDate).Where(c => (c.TradeType != "结构化交易" || c.IsGroup == 1) && tradeIds.Contains(c.id));
if (TradeQuery.Any())
{
var group = TradeQuery.GroupBy(O => new { O.ClientId, O.TradeDate }).ToDictionary(K => K.Key, V => V.Select(O => O.id).ToList());
// 按照客户ID、交易日期、多空头进行分组
var group = TradeQuery.GroupBy(O => new { O.ClientId, O.TradeDate, O.swap_positions.FirstOrDefault().PositionType})
.ToDictionary(K => K.Key, V => V.Select(O => O.id).ToList());
foreach (var item in group)
{
var query = from t in DbContext.trade
join tc in DbContext.trade_cash on t.id equals tc.TradeId
where t.ClientId == item.Key.ClientId &&
tc.ValueDate == item.Key.TradeDate && !tc.IsDeleted && tc.Action == ClientCashInCashOut._期权费
select new { t.id };
if (query.Any())
{
groupGenerateHandle(query.Select(l => l.id).ToList(), docType, startDate, endDate, results, error, file);
}
}
}
}
else if(PS.Config.Is物产中大)
{
var TradeQuery = new TradeDalService(this).GetTradeOrEodTradeOfTidASid(tradeIds, SystemValueDate).Where(c => (c.TradeType != "结构化交易" || c.IsGroup == 1) && tradeIds.Contains(c.id));
if (TradeQuery.Any())
{
var group = TradeQuery.GroupBy(O => new { O.ClientId, O.TradeDate,O.TradeType }).ToDictionary(K => K.Key, V => V.Select(O => O.id).ToList());
foreach (var item in group)
{
if (item.Value.Count > 10)
{
throw new ServiceException("同客户同日期同类型交易生成超过限制!");
}
// 如果是结构化交易或特殊交易类型需要额外处理,这里简化处理
var query = from t in DbContext.trade
join tc in DbContext.trade_cash on t.id equals tc.TradeId
where item.Value.Contains(tc.TradeId) && !tc.IsDeleted
select new { t.id };
if (query.Any())
{
groupGenerateHandle(query.Select(l => l.id).ToList(), docType, startDate, endDate, results, error, file);
// 使用现有的 groupGenerateHandle 方法来处理每组交易
groupGenerateHandle(query.Select(l => l.id).Distinct().ToList(), docType, startDate, endDate, results, error, file);
}
}
}
@@ -681,6 +530,97 @@ namespace YLErp.Modules.TradeModule.DealModule
return query.ToArray();
}
public SearchListResult<clientContractR> GetConfirmBookListByClient(ClientConfirmBookListReq req)
{
var result = new SearchListResult<clientContractR>();
var contractList = new List<clientContractR>();
// Fix for the issue: CS1525, CS0746, CS1003
// The problem lies in the incorrect syntax for defining an anonymous type.
// Anonymous type members must be declared using member assignment or simple names.
var query = from t in DbContext.trade.AsNoTracking().Where(x => x.TradeType == "收益互换" && x.ValidState != "InValid")
join tcrs in DbContext.trade_contract_r
on t.id equals tcrs.TradeId into tcrsGroup
from tcr in tcrsGroup.Where(r => r.IsValid && r.Type == ContractTypeEnum.Trade).DefaultIfEmpty()
join tcds in DbContext.trade_contract_document
on tcr.ContractCode equals tcds.Code into tcdsGroup
from tcd in tcdsGroup.DefaultIfEmpty()
join sp in DbContext.swap_position.AsNoTracking().Where(s => s.IsInitial && s.PositionType > 0 && !s.Invalid)
on t.id equals sp.SwapTradeId
select new
{
t.id,
t.TradeDate,
tcr.ContractCode,
t.ClientId,
t.ClientNumber,
t.ClientName,
tcr.send_email_result,
tcd.Status,
tcd.RelativePath,
tcd.SealResult,
ContractId = tcr != null ? tcr.id : 0,
sp.PositionType,
t.SentMailCount
};
if (req.StartDate != null && req.StartDate != DateTime.MinValue)
{
query = query.Where(o => o.TradeDate >= req.StartDate);
}
if (req.EndDate != null && req.EndDate != DateTime.MaxValue)
{
query = query.Where(o => o.TradeDate <= req.EndDate);
}
if (req.ClientIds != null && req.ClientIds.Count > 0)
{
query = query.Where(o => req.ClientIds.Contains(o.ClientId));
}
if (!string.IsNullOrEmpty(req.ContractCode))
{
query = query.Where(o => o.ContractCode.Contains(req.ContractCode));
}
if (req.PositionTypes!= null && req.PositionTypes.Count() > 0)
{
query = query.Where(o => req.PositionTypes.Contains(o.PositionType));
}
var contractGroups = query.AsEnumerable()
.GroupBy(x => new { x.TradeDate, x.ClientId, x.PositionType })
.Select(group => group.ToList())
.ToList();
// 构建返回结果
foreach (var group in contractGroups)
{
var sealResult = group.FirstOrDefault().SealResult;
contractList.Add(new clientContractR
{
id = group.FirstOrDefault().id,
ContractCode = group.FirstOrDefault().ContractCode,
TradeDate = group.FirstOrDefault().TradeDate.Value,
ClientNumber = group.FirstOrDefault().ClientNumber,
ClientName = group.FirstOrDefault().ClientName,
StampStatus = group.FirstOrDefault().Status,
EmailResult = group.FirstOrDefault().send_email_result,
ContractDocUrl = group.FirstOrDefault().RelativePath,
tradeIds = group.Select(x => x.id).Distinct().ToList(),
SealResult = sealResult != null ? Enum.GetName(typeof(SealResultEnum), sealResult) : "",
HasGeneratedConfirmBook = group.FirstOrDefault().ContractId != 0,
ContractId = group.FirstOrDefault().ContractId,
tradeCount = group.Select(x => x.id).Distinct().Count(),
PositionType = group.FirstOrDefault().PositionType,
SentMailCount = group.FirstOrDefault().SentMailCount ?? 0,
});
}
result = contractList.AsQueryable().ToSearchList(req);
return result;
}
}
/// <summary>
@@ -696,4 +636,58 @@ namespace YLErp.Modules.TradeModule.DealModule
public Exception Exception;
}
public class ClientConfirmBookListReq : BaseSearchReq
{
//合约编号
public string ContractCode { get; set; }
//开仓起始时间
public DateTime? StartDate { get; set; }
//开仓结束时间
public DateTime? EndDate { get; set; }
//客户
public List<int>? ClientIds { get; set; }
public List<int>? PositionTypes { get; set; }
}
public class clientContractR
{
public int id { get; set; }
public string ContractCode { get; set; }
public DateTime TradeDate { get; set; }
public string ClientNumber { get; set; }
public string ClientName { get; set; }
public string StampStatus { get; set; }
public string EmailResult { get; set; }
public List<int> tradeIds { get; set;}
public string ContractDocUrl { get; set; }
public string SealResult { get; set; }
public string ContractEncryptId { get; set; }
public bool HasGeneratedConfirmBook { get; set; }
public int ContractId { get; set; }
public int PositionType { get; set; }
public int tradeCount { get; set; }
public int SentMailCount { get; set; }
}
}
@@ -21,6 +21,7 @@ using YLErp.Configuration;
using YLErp.DBModels;
using YLErp.DBModels.Abstract;
using YLErp.DBModels.Consts;
using YLErp.DBModels.Enums;
using YLErp.Helpers;
using YLErp.Model;
using YLErp.Models;
@@ -1323,6 +1324,13 @@ namespace YLErp.Modules.TradeModule.DocGenerateModule
{
return UniqueTimeId.GetStr();
}
if (Trade.TradeType == "收益互换")
{
var posi = GetSwapPositions(Trade.id, true).FirstOrDefault();
var isLong = posi?.PositionType == (int)PositionTypeFlag.Short ? false : true;
return "ZSZQ-" + _client.Number + "-" + Trade.TradeDate?.ToString("yyyyMMdd") + (isLong ? "-L" : "-S");
}
return Trade.TradeNumber;
}
/// <summary>
@@ -162,38 +162,48 @@ namespace YLErp.Modules.TradeModule.DocGenerateModule
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);
foreach (var tradeContractGroup in tradeDic.Values)
if (PS.Config.Company == Configuration.CompanyEnum.)
{
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)))
if (generatorV2 != null)
{
resultList.Add(new TradeDocGenerateResult(tradeContractGroup.trade)
{
ErrorMessage = "缺少现金交割记录"
});
}
//插件版本
else if (generatorV2 != null)
{
var result = GenerateSingleV2(generatorV2, tradeContractGroup, docType);
var result = GenerateSingleV2(generatorV2, null, docType , allTradeList);
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;
// }
//}
}
}
else
{
foreach (var tradeContractGroup in tradeDic.Values)
{
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)
{
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();
@@ -205,14 +215,21 @@ namespace YLErp.Modules.TradeModule.DocGenerateModule
/// <summary>
///
/// </summary>
private TradeDocGenerateResult GenerateSingleV2(ITradeConfirmationGenerator generator, trade_contract_group tradeContractGroup, string docType = "DOCX")
private TradeDocGenerateResult GenerateSingleV2(ITradeConfirmationGenerator generator, trade_contract_group tradeContractGroup, string docType = "DOCX", List<trade> allTrades = null)
{
try
{
//修改调用的构造方法
List<trade> trades = new List<trade>() { tradeContractGroup.trade };
List<trade> trades = new List<trade>();
if (allTrades != null && allTrades.Count() > 0)
{
trades = allTrades;
}else
{
trades = new List<trade>() { tradeContractGroup.trade };
}
List<int> ids = new List<int>();
if (tradeContractGroup.trade != null && tradeContractGroup.trade.trade_cash != null)
if (tradeContractGroup != null && tradeContractGroup.trade != null && tradeContractGroup.trade.trade_cash != null)
{
ids.Add(tradeContractGroup.trade.trade_cash.id);
}
@@ -759,27 +776,26 @@ namespace YLErp.Modules.TradeModule.DocGenerateModule
}
}
public (bool, string, DateTime, string) UploadContractFileNew(string encryptId, UploadFileModel uploadFileModel)
public (bool, string, DateTime, string) UploadContractFileNew(string contractCode, UploadFileModel uploadFileModel)
{
try
{
var msg = "";
#region
if (string.IsNullOrWhiteSpace(encryptId))
if (string.IsNullOrWhiteSpace(contractCode))
{
return (false, "请传入id", DateTime.Now, "");
return (false, "请传入参数", DateTime.Now, "");
}
var intid = DataProtectHelper.DecryptInt(encryptId);
var db = DbContextFactory.GetYLDbContext();
var contractDoc = db.trade_contract_document.Find(intid);
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 contractDocR = contractDocRArr.FirstOrDefault();
if (contractDoc == null || contractDocR == null)
var contractDocRF = contractDocRArr.FirstOrDefault();
if (contractDoc == null || contractDocRF == null)
{
return (false, "没有相关的确认书文档", DateTime.Now, "");
}
@@ -806,9 +822,9 @@ namespace YLErp.Modules.TradeModule.DocGenerateModule
#endregion
var tradeNumber = "未知";
if (contractDocR != null)
if (contractDocRF != null)
{
tradeNumber = contractDocR.TradeNumber;
tradeNumber = contractDocRF.TradeNumber;
}
var filePath = Path.Combine(OtcAppContext.AppDocsPath, "contractdoc", "output");
@@ -841,8 +857,12 @@ namespace YLErp.Modules.TradeModule.DocGenerateModule
}
#region
var confrimService = new TradeConfirmService(OptUser, db);
foreach (var contractDocR in contractDocRArr)
{
new TradeConfirmService(OptUser, db).EditReportStatus(contractDocR.TradeId, true);
}
new TradeConfirmService(OptUser, db).EditReportStatus(contractDocR.TradeId, true);
db.SaveChanges();
#endregion
+1 -1
View File
@@ -21,7 +21,7 @@
{Name:"成交簿记",Rights:["结算管理-成交簿记"],Url:"swaptrade2/SwapflowList"},
{Name:"资金记录",Rights:["结算管理-出入金维护"],Url:"entryexit/entryexitList"},
{Name:"收盘操作",Rights:["结算管理-收盘操作"],Url:"eod_trade_value/eodExec"},
{Name:"交易确认书",Rights:["结算管理-交易确认书"],Url:"TradeConfirmBook/Index"},
{Name:"交易确认书",Rights:["结算管理-交易确认书"],Url:"TradeConfirmBook/ConfirmBookListByClient"},
{Name:"结算确认书",Rights:["结算管理-结算确认书"],Url:"swaptrade2/tradeEndConfirmList"},
{Name:"每日估值报告",Rights:["结算管理-每日估值报告"],Url:"clientbalance/TradeMarketReport"},
]
+2 -2
View File
@@ -1033,10 +1033,10 @@ namespace YLErp.Web.Controllers
/// </summary>
/// <param name="tradeId"></param>
/// <returns></returns>
public JsonResult SendConfimEmail(int tradeId)
public JsonResult SendConfimEmail(string contractCode)
{
SwapEndConfirmService service = new SwapEndConfirmService(CurUser);
var result = service.SendConfirmEamil(tradeId);
var result = service.SendConfirmEamil(contractCode);
return JsonSuccess(result);
}
}
@@ -6,6 +6,7 @@ using YLErp.CustomizedBizLogic;
using YLErp.DBModels.Consts;
using YLErp.Enums;
using YLErp.Model;
using YLErp.Model.Enum;
using YLErp.Modules.AppModule;
using YLErp.Modules.ClientModule;
using YLErp.Modules.ReportModule;
@@ -75,6 +76,17 @@ namespace YLErp.Web.Controllers
return JsonError("申万定制功能,当前已不支持");
}
public ActionResult ConfirmBookListByClient()
{
return View();
}
public JsonResult clientConfirmQuery(ClientConfirmBookListReq req)
{
var result = new TradeContractGenerateService(CurUser).GetConfirmBookListByClient(req);
return Json(result);
}
public async Task<ActionResult> SentMail(string enid, List<string> reciver)
{
var result = await DoSendMailSywg(enid, reciver);
+10 -3
View File
@@ -2031,10 +2031,10 @@ namespace YLErp.Web.Controllers
}
return JsonError(msg);
}
public ActionResult UploadContractFileNew(string encryptId)
public ActionResult UploadContractFileNew(string contractCode)
{
var uploadFileModel = Request.Form.Files.Count > 0 ? Request.Form.Files[0].ToUploadFileModel() : null;
var (flag, msg, optDate, stampPath) = new ConfirmationGenerateService(CurUser).UploadContractFileNew(encryptId, uploadFileModel);
var (flag, msg, optDate, stampPath) = new ConfirmationGenerateService(CurUser).UploadContractFileNew(contractCode, uploadFileModel);
if (flag)
{
@@ -6325,6 +6325,11 @@ namespace YLErp.Web.Controllers
isSelect = true;
query = query.Where(O => req.TradeCashIds.Contains(O.TradeCashId));
}
if (req.ContractCodes != null && req.ContractCodes.Any(O => !string.IsNullOrWhiteSpace(O)))
{
isSelect = true;
query = query.Where(O => req.ContractCodes.Contains(O.ContractCode));
}
if (req.DocType != null)
{
query = query.Where(O => O.Type == req.DocType);
@@ -6353,13 +6358,15 @@ namespace YLErp.Web.Controllers
}
}
var datas = query.ToList();
var datas = query.ToList();
if (datas.Count == 0)
{
return ShowError("未找到确认书文件,请确认筛选条件是否有效!");
}
datas = datas.DistinctBy(O => O.ContractCode).ToList();
var filePathList = new List<string>(datas.Count * req.docpdf.Count());
var contractBLL = new TradeContractBLL(CurUser);
+19 -17
View File
@@ -12,7 +12,7 @@ namespace YLErp.Web.Hubs
{
private static bool isProcessing = false;
static readonly Dictionary<string, DateTime> _dic = new Dictionary<string, DateTime>(StringComparer.OrdinalIgnoreCase);
static readonly Dictionary<int, string> _clientProgressDic = new Dictionary<int, string>();
static readonly Dictionary<string, string> _clientProgressDic = new Dictionary<string, string>();
public async Task StartProcessing(string jsonString)
{
SwapTradeSendEmailReq req = JsonHelper.Deserialize<SwapTradeSendEmailReq>(jsonString);
@@ -33,11 +33,11 @@ namespace YLErp.Web.Hubs
if (isProcessing)
{
await client.SendAsync("ExceptionMessage", "正在发送邮件,请稍后再试");
foreach (var tradeId in req.tradeIds) {
var msg= GetProcess(tradeId,async (d) => {
await client.SendAsync("UpdateProgress", getUpdateProcess(tradeId, d));
foreach (var contractCode in req.contractCodes) {
var msg= GetProcess(contractCode, async (d) => {
await client.SendAsync("UpdateProgress", getUpdateProcess(contractCode, d));
});
await client.SendAsync("UpdateProgress", getUpdateProcess(tradeId, msg));
await client.SendAsync("UpdateProgress", getUpdateProcess(contractCode, msg));
}
await client.SendAsync("ProcessCompleted", "");
return;
@@ -47,10 +47,11 @@ namespace YLErp.Web.Hubs
isProcessing = true;
_clientProgressDic.Clear();
_dic.Clear();
foreach (var tradeId in req.tradeIds)
//根据tradeIds 获取contractCode
foreach (var contractCode in req.contractCodes)
{
_clientProgressDic[tradeId] = "发送中";
await client.SendAsync("UpdateProgress", getUpdateProcess(tradeId, "发送中"));
_clientProgressDic[contractCode] = "发送中";
await client.SendAsync("UpdateProgress", getUpdateProcess(contractCode, "发送中"));
if (PS.Config.ErpElement.MailMessageRateLimit > 0)
{
var milliSeconds = 60d * 1000 / PS.Config.ErpElement.MailMessageRateLimit;
@@ -67,9 +68,9 @@ namespace YLErp.Web.Hubs
_dic["sendEmail"] = DateTime.Now;
}
}
var result = service.SendConfirmEamil(tradeId);
_clientProgressDic[tradeId] = result;
await client.SendAsync("UpdateProgress", getUpdateProcess(tradeId, result));
var result = service.SendConfirmEamil(contractCode);
_clientProgressDic[contractCode] = result;
await client.SendAsync("UpdateProgress", getUpdateProcess(contractCode, result));
}
isProcessing = false;
await client.SendAsync("ProcessCompleted", "");
@@ -80,26 +81,27 @@ namespace YLErp.Web.Hubs
await client.SendAsync("ExceptionMessage", ex.Message);
}
}
private string GetProcess(int tradeId,Action<string> action)
private string GetProcess(string contractCode, Action<string> action)
{
if (_clientProgressDic.ContainsKey(tradeId))
if (_clientProgressDic.ContainsKey(contractCode))
{
string process= _clientProgressDic[tradeId];
string process= _clientProgressDic[contractCode];
if (action != null&& process=="发送中")
{
action.Invoke(process);
Thread.Sleep(1000);
return GetProcess(tradeId, action);
return GetProcess(contractCode, action);
}
return process;
}
return "";
}
private string getUpdateProcess(int tradeId,string msg)
private string getUpdateProcess(string contractCode, string msg)
{
SwapTradeSendEmailResp resp = new SwapTradeSendEmailResp()
{
tradeId = tradeId,
contractCode = contractCode,
send_email_result = msg
};
return JsonHelper.Serialize(resp);
@@ -0,0 +1,84 @@
@{
ViewBag.Title = "交易确认书"; // 设置页面标题
Layout = "~/Views/Shared/_MainLayout.cshtml"; // 指定布局页面
// 定义页面JS对象,用于传递后端数据到前端JS
var pageObj = new
{
// 获取客户确认书列表数据的URL
clientConfirmQueryUrl = Url.Action("clientConfirmQuery", "TradeConfirmBook"),
// 获取所有客户数据的URL (假设存在一个获取客户列表的方法)
getAllClientsUrl = Url.Action("GetAllClient", "ClientData"), // 请确保ClientDataController中有GetAllClient方法或使用正确的获取客户数据方法
ConfirmBookStampStatus = PS.Config.ErpElement.ConfirmBookStampStatus,
valuedate = valuedateBLL.ValueDate.ToString("yyyy-MM-dd"),
SettleDocModeMultiple = valuedate.SettleDocModeMultiple.Equals(valuedateBLL.SystemDate.SettleDocMode),
BrokerMode = YLErp.PS.Config.ComponentVersion == YLErp.Configuration.ComponentVersion.Broker,
MarketMaker = YLErp.PS.Config.ComponentVersion == YLErp.Configuration.ComponentVersion.MarketMaker,
reqTradeStatus = $"{ConsTrade.确认成交},{ConsTrade.已到期},{ConsTrade.已平仓},{ConsTrade.已执行}",
SelectConfirmationBookTemplate = GlobalConfig.SelectConfirmationBookTemplate == true,
templateNames = ViewBag.TemplateNames,
IsAutoSealAndUploadFiles = YLErp.PS.GetErpConfig().IsAutoSealAndUploadFiles,
IsZheQi = PS.Config.Is浙期,
IsAutoSealAfterGeneratedBook = PS.GetErpConfig().IsAutoSealAfterGeneratedBook,
canGenerate = CurUser.结算管理_交易确认书生成,
canSendEmail = CurUser.结算管理_交易确认书邮件发送
};
}
@section CSS{
<style>
/* 可以添加此页面特定的CSS样式 */
.searchdiv .search-group { /* 调整搜索项间距 */
margin-right: 10px;
margin-bottom: 5px;
}
</style>
}
@section JS{
@* 引入必要的JS库 *@
<script src="~/statics/libs/signalr/dist/browser/signalr.min.js"></script>
<script src="~/Scripts/app/tradeHelper.js?v=@HtmlUtil.JsVersion"></script>
<script type="text/javascript">
var page = @Json.Serialize(pageObj);
</script>
@* 引入此页面对应的JS逻辑文件 *@
<script src="~/Scripts/app/trade/tradeConfirmBookListByClient.js?v=@(HtmlUtil.JsVersion)"></script>
}
@* 搜索区域 *@
<div class="searchdiv">
@* 合约编号输入框 *@
@Html.ShortInput("ContractCode", "合约编号")
@* 客户名称下拉框 (使用MyAceDropdownInput,假设ClientDataModel.GetAllClient()能获取所需数据格式) *@
@Html.MyAceDropdownInput("ClientIds", "客户名称", ClientDataModel.GetAllClient(), true) @* true表示允许多选 *@
@* 开仓日期范围选择 *@
@Html.SearchDateRange("OpenDate", "开仓日期")
@* 多空头方向选择 *@
@Html.MyAceDropdownInput("MultiHead", "多空头方向", new List<SelectListItem>
{
new SelectListItem { Text = "多头", Value = "1" },
new SelectListItem { Text = "空头", Value = "2" },
})
@MyControls.SearchBtn()
@if (pageObj.canGenerate)
{
@MyControls.Btn("批量生成交易确认书", "BatchCreateContracts()")
}
@MyControls.Btn("批量下载交易确认书", "BatchDownLoadDoc()")
<button class="btn btn-primary" id="batchSendEmail" style="margin-left:16px;">批量发送邮件</button>
@if (PS.GetErpConfig().IsAutoSealAndUploadFiles && !PS.GetErpConfig().IsAutoSealAfterGeneratedBook)
{
@MyControls.Btn("批量确认书用印", "BatchSealContracts()")
}
<div style="width:30px;display:inline-block; vertical-align: middle; cursor:pointer;" onclick="showcolumnChooser();return false;">
<img src="~/Images/configure.png"/>
</div>
</div>
@Html.Raw(JqGridSimple.OutTable())
@* 可能需要的其他HTML元素,例如下载链接的占位符 *@
<a download="" href="" target="_blank" id="downLink" style="display:none;"></a>
@@ -41,7 +41,7 @@
for (var x = 0; x < files.length; x++) {
data.append(files[x].name, files[x]);
}
data.append("encryptId", encryptId);
data.append("contractCode", encryptId);
$.ajax({
type: "Post",
@@ -0,0 +1,552 @@
// tradeConfirmBookListByClient.js
const colModelGrid = (new function () {
// 定义列模型
this.colModels = [
{
name: '',
label: '操作',
width: 450,
align: 'left',
formatter: showToolName
}, {
name: 'ClientId',
hidden: true,
optionHide: true
},
{
name:"id",
label: 'id',
width: 100,
hidden: true,
key: true,
},{ label: '合约编号', name: 'ContractCode', width: 150, },
{ label: '客户名称', name: 'ClientName', width: 150 },
{ label: '交易日期', name: 'TradeDate', width: 100, align: 'center' ,formatter: 'date' },
{ label: '多空头', name: 'PositionType', width: 80, align: 'center',
formatter: function (cellValue, options, rowObject) {
return cellValue == 1 ? "多头" : "空头";
}
},
{ label: '用印状态', name: 'StampStatus', width: 80, align: 'center' }, // 根据实际需要调整宽度和对齐
{ label: '邮件发送结果', name: 'EmailResult', width: 100, align: 'center',
formatter: function (cellValue, options, rowObject) {
console.log(cellValue);
var html = "";
html += "<label>{0}</lable>".template( rowObject.EmailResult);
return html;
}
},
{ label: '交易数量', name: 'tradeCount', width: 80, align: 'center' },
{ label: 'tradeIds', name: 'tradeIds', hidden: true }];
this.upload = function (encryptId, sendMail) {
var srcurl = "/TradeConfirmBook/confirmBookUpload/?Id=" + encryptId + "&SendMailId=" + sendMail;
main.open("上传确认书", srcurl, {
area: ['500px', '420px'],
end: function () { SearchClick(true) }
});
}
this.uploadNew = function (encryptId) {
var srcurl = "/TradeConfirmBook/confirmBookUploadNew/?Id=" + encryptId;
main.open("上传确认书", srcurl, {
area: ['500px', '420px'],
end: function () { SearchClick(true) }
});
}
}());
$(function () {
// 初始化jqGrid
initJqGrid();
$("#DateFromOpenDate").datepicker({
changeMonth: true, changeYear: true, showButtonPanel: true, showOtherMonths: true, selectOtherMonths: true,
onSelect: function (selectedDate) {//选择日期后执行的操作
setValidation("DateToOpenDate", selectedDate, false);
}
});
$("#DateToOpenDate").datepicker({
changeMonth: true, changeYear: true, showButtonPanel: true, showOtherMonths: true, selectOtherMonths: true,
onSelect: function (selectedDate) {//选择日期后执行的操作
setValidation("DateFromOpenDate", selectedDate, true);
}
});
// 其他按钮事件绑定 (如果添加了批量操作按钮)
// $("#batchDownloadBtn").click(BatchDownLoadDoc);
// $("#batchSendMailBtn").click(BatchSendMail);
SendEmailHub()
});
// 初始化jqGrid函数
function initJqGrid() {
var PostData = {
ContractCode: $("#ContractCode").val(),
ClientIds: $("#ClientIds").val(), // 获取多选下拉框的值
StartDate: $("#DateFromOpenDate").val(),
EndDate: $("#DateToOpenDate").val(),
}
var __jq = {
AfterInsertRow: typeof AfterInsertRow !== 'undefined' ? AfterInsertRow : void 0,
rowclick: typeof rowclick !== 'undefined' ? rowclick : void 0,
rowdblclick: typeof rowdblclick !== 'undefined' ? rowdblclick : void 0,
gridComplete: typeof gridComplete !== 'undefined' ? gridComplete : void 0,
onJqgridPaging: typeof onJqgridPaging !== 'undefined' ? onJqgridPaging : void 0
};
var grid = jQuery('#listGrid').jqGrid({
url: page.clientConfirmQueryUrl, // 从page对象获取数据URL,
datatype: page.initEmptyView ? 'local' : 'json',
height: 'auto',
width: '90%',
autowidth: false,
shrinkToFit: false,
viewrecords: true,
jsonReader: { repeatitems: false },
cmTemplate: { align: 'center', width: 120 },
mtype: 'POST',
postData: PostData,
afterInsertRow: __jq.AfterInsertRow,
onSelectRow: __jq.rowclick,
ondblClickRow: __jq.rowdblclick,
colModel: colModelGrid.colModels,
pager: jQuery('#pagerGrid'),
pagerpos: 'left',
rowNum: 20,
rowList: [20, 30, 50, 200, 10000],
loadComplete: __jq.gridComplete,
onPaging: __jq.onJqgridPaging,
multiselect: !(page.SettleDocModeMultiple && page.BrokerMode)
});
page.initEmptyView && jQuery("#listGrid").jqGrid('setGridParam', { datatype: 'json' });
}
// 重新加载jqGrid数据函数
function reloadJqGrid() {
SearchClick();
$('#modal-edittrade').modal('hide');
}
function SearchClick(isSearchclick) {
var listGrid = $('#listGrid');
listGrid.appendPostData({ ContractCode: $("#ContractCode").val() });
listGrid.appendPostData({ ClientIds: $("#ClientIds").val()});
listGrid.appendPostData({ StartDate: $("#DateFromOpenDate").val() });
listGrid.appendPostData({ EndDate: $("#DateToOpenDate").val() });
listGrid.appendPostData({ PositionTypes: $("#MultiHead").val() });
if (isSearchclick) {
//点击搜索时默认第一页
listGrid.jqGrid('setGridParam', { page: 1 });
}
listGrid.trigger('reloadGrid');
}
function showToolName(cellValue, options, rowObject) {
var sentMailCount = rowObject.SentMailCount;
if (!sentMailCount) {
sentMailCount = 0;
}
var html = showDownload(cellValue, options, rowObject);
var title = page.IsAutoSealAndUploadFiles && page.IsAutoSealAfterGeneratedBook ? "生成并用印" : "生成确认书";
var canGenerate = page.canGenerate == true ? "" : "disabled";
var isWait = (rowObject.SealResult == "用印等待中");
html += "<input type=\"button\" class='wentiEdit' title='{2}' onclick=\"gJGenerateConfirmBook([{0}],{3},{1})\" value='{2}' {4}/>".template(rowObject.tradeIds, rowObject.HasGeneratedConfirmBook, title, isWait, canGenerate);
if (rowObject.ContractDocUrl && page.canSendEmail == true) {
html += "<input type=\"button\" class=\"wentiEdit\" title='发送交易所在的交易确认书到客户对应接收Email' onclick=\"sentMail('{0}')\" value=\"{1}\" />"
.template(rowObject.ContractCode, "发送Email");
} else {
html += "<input type=\"button\" class=\"wentiEdit\" title='交易确认书未生成或未找到制定确认书文件' disabled readonly=\"true\" value=\"{1}\" />"
.template(rowObject.EncryptId, "发送Email");
}
var canUpload = page.canGenerate == true && rowObject.ContractDocUrl ? "" : "disabled";
html += "<input type=\"button\" class=\"wentiEdit\" value=\"上传\" onclick=\"colModelGrid.uploadNew('{0}')\" {1} />".template(rowObject.ContractCode, canUpload);
return html;
}
function setValidation(elId, selectedDate, isSetMax) {
if (isSetMax) {
var time = selectedDate.split("-");
var year = time[0];
var month = time[1] - 1;
var day = time[2];
$("#" + elId).datepicker(
'option', 'maxDate', new Date(year, month, day)
);
} else {
let time = selectedDate.split("-");
let year = time[0];
let month = time[1] - 1;
let day = time[2];
$("#" + elId).datepicker(
'option', 'minDate', new Date(year, month, day)
);
}
}
function reloadtrade() {
//重新加载
SearchClick();
$('#modal-edittrade').modal('hide');
}
function showDownload(cellvalue, options, rowObject) {
var html = "";
if (rowObject.ContractDocUrl) {
html += "<input type=\"button\" class=\"wentiEdit\" title='下载交易确认书' onclick=\"DownLoadDoc('{0}')\" value=\"{1}\" />"
.template(rowObject.ContractDocUrl, "下载");
} else {
html += "<input type=\"button\" class=\"wentiEdit\" title='交易确认书未生成或未找到制定确认书文件' readonly=\"true\" value=\"{1}\" />"
.template(rowObject.ContractDocUrl, "下载");
}
return html;
}
function gJGenerateConfirmBook(ids, isWait, hasGeneratedConfirmBook) {
if (page.IsAutoSealAndUploadFiles) {
//if (isWait) {
// if (!confirm("用印正在等待中重新生成将中断用印并重新进行自动用印(如有),是否确认操作?")) {
// return;
// }
//}
if (!confirm("重新生成将覆盖已有的交易确认书并重新进行自动用印(如有),是否确认操作?")) {
return;
}
}
if (hasGeneratedConfirmBook == "True") {
if (!page.IsAutoSealAndUploadFiles) {
if (!confirm("确认覆盖已有的交易确认书?")) {
return;
}
}
}
var tradeIds = [];
if (ids) {
tradeIds = ids
} else {
//获取选中项的jqGrid对象的tradeIds
var jgrid = jQuery('#listGrid');
var rowIds = jgrid.jqGrid('getGridParam', 'selarrrow');
rowIds.forEach((v, i, arr) => {
var rowId = v;
var data = jgrid.jqGrid('getRowData', rowId);
var idArray = data.tradeIds.split(",");
tradeIds.push(idArray);
});
}
if (tradeIds.length === 0) {
main.message("请选择交易");
return;
}
var templateHtml = "";
if (page.SelectConfirmationBookTemplate) {
var currentTemplate = "";
var postData = {
key: "交易确认书"
};
if (tradeIds.length === 1) {
postData.tradeId = tradeIds[0];
main.post("/trade/GetTradeMeta", postData, { waitMe: false, async: false }).done(function (res) {
currentTemplate = res;
});
}
templateHtml = '<div class="form-group">' +
'<label class="col-sm-4 control-label">选择模板</label>' +
'<select style="width: 145px; margin-left: 14px;" data-placeholder="请选择 确认书模板" name="templateName">' +
'<option ' +
(currentTemplate === "" ? "selected" : "") +
' value="">默认</option>';
if (page.templateNames !== null) {
page.templateNames.forEach((t, i, arr) => {
templateHtml += '<option ' +
(currentTemplate !== "" && currentTemplate === t ? "selected" : "") +
' value="{0}">{0}</option>'.template(t);
});
}
templateHtml += '</select>' +
'</div>';
}
var htmlContent = '<form class="form-horizontal" role="form" style="padding:15px 12px 5px">' +
'<div class="form-group">' +
'<label class="col-sm-4 control-label">文档类型</label>' +
'<div class="btn-group col-sm-8" data-toggle="buttons">' +
'<label class="btn btn-sm btn-primary" style="border:none"><input type="radio" checked name="docType" value="DOCX"> DOC</label>' +
'<label class="btn btn-sm btn-primary active" style="border:none"><input type="radio" name="docType" value="PDF"> PDF</label>' +
'</div>' +
'</div>' +
templateHtml +
'</form>';
main.open2("生成交易确认书",
htmlContent,
{
area: ["300px", "200px"],
btn: ['生成', '取消'],
yes: function (index, layero) {
var docType = $('input[name="docType"]:checked').val();
if (page.SelectConfirmationBookTemplate) {
postData.value = $('select[name="templateName"]').val();
if (_.trim(postData.value)) {
tradeIds.forEach((v, i, arr) => {
postData.tradeId = v;
main.post("/trade/SetTradeMeta", postData, { waitMe: false, async: false });
});
}
}
var confirmBookPostData = { tradeIds: tradeIds, docType: docType, startDate: $("#DateFromTradeDate").val(), endDate: $("#DateToTradeDate").val() };
//if (page.IsAutoSealAndUploadFiles) {
// confirmBookPostData.SealResults = $("#SealResults").val();
// //confirmBookPostData.SealDateStart = $("#DateFromSealDate").val();
// //confirmBookPostData.SealDateEnd = $("#DateToSealDate").val();
//}
main.post("/TradeConfirmBook/GJGenerateConfirmBook/", confirmBookPostData)
.done(function (resp) {
var res = resp.obj;
//for (let index = 0; index < resp.obj.length; index++) {
// if (!isExistFile(res[index])) {
// res[index] += "x";
// }
//}
if (resp.success) {
main.downloadFiles(res);
} else {
main.alert(resp.msg.replace("\r\n", "<br/>"));
//if (resp.obj) {
// main.downloadFiles(res);
//}
}
window.reloadtrade();
window.layer.closeAll();
});
},
cancel: function (index, layero) {
parent.layer.closeAll();
},
success: function (layero, index) {
$(".btn-group").on("click", ".btn", function (event) {
$('input[name="docType"]:checked').prop("checked", false);
$(this).children("input").prop("checked", true);
});
}
});
}
function DownLoadDoc(res) {
if (isExistFile(res)) {
window.open(res);
} else {
res += "x";
if (isExistFile(res)) {
window.open(res);
} else {
main.confirm("文件不存在");
}
}
}
function isExistFile(url) {
var result = false;
main.post("/TradeConfirmBook/ExistFile", { filePath: url }, { async: false }).done(function (res) {
if (res && res.obj) {
result = true;
}
});
return result;
}
function sentMail(contractCode) {
main.post("/swaptrade2/SendConfimEmail?contractCode=" + contractCode).done(function (res) {
if (res.success) {
SearchClick(true);
}
});
}
function BatchCreateContracts() {
var jgrid = jQuery('#listGrid');
var tradeIds = main.GetGridIds(jgrid);
if (tradeIds.length == 0) {
main.alert("请至少选择一笔交易"); return;
}
main.confirm("确认为所勾选的交易生成交易确认书?", function () {
gJGenerateConfirmBook();
});
}
//批量下载交易确认书
function BatchDownLoadDoc() {
var startDate = $("#DateFromTradeDate").val();
var endDate = $("#DateToTradeDate").val();
var clientIds = $("#ClientId").val();
var contractCodes = [];
var jgrid = jQuery('#listGrid');
var rowIds = jgrid.jqGrid('getGridParam','selarrrow');
rowIds.forEach((v, i, arr) => {
var rowId = v;
var data = jgrid.jqGrid('getRowData', rowId);
contractCodes.push(data.ContractCode);
})
var tip = "下载" + startDate + "至" + endDate + "的交易确认书";
if (contractCodes) { tip = "下载所有已勾选的交易确认书"; }
var htmlContent = '<form class="form-horizontal" role="form" style="padding:15px 12px 5px">' +
'<div class="form-group">' +
'<label style="padding:10px 12px 10px">' + tip + '</label><br />' +
'<label class="col-sm-5 control-label">文档类型</label>' +
'<label class="btn btn-sm btn-primary" style="border:none"><input type="checkbox" checked name="docType" value="DOC"> DOC</label>' +
'<label class="btn btn-sm btn-primary" style="border:none"><input type="checkbox" checked name="docType" value="PDF"> PDF</label>';
if (page.IsZheQi) {
htmlContent += '<br/><label class="col-sm-5 control-label">下载用印文件</label>' +
'<select id="Seal" style="margin-top:5px;"><option>是</option><option>否</option></select>';
}
main.open2("批量下载交易确认书",
htmlContent + '</div></form>',
{
area: ["400px", "250px"],
btn: ['下载', '取消'],
yes: function (index, layero) {
var docpdf = [];
$('input[name="docType"]:checked').each(function (i) {
docpdf.push($(this).val())
})
var isSeal = $("#Seal").val() == '是' ? true : false;
var confirmBookPostData = { TradeDateStart: startDate, TradeDateEnd: endDate, ClientIds: clientIds, TradeIds: null, TradeCashIds: null,contractCodes : contractCodes, DocType: "交易确认书", docpdf: docpdf, IsSeal: isSeal };
if (page.IsAutoSealAndUploadFiles) {
confirmBookPostData.SealResults = $("#SealResults").val();
//confirmBookPostData.SealDateStart = $("#DateFromSealDate").val();
//confirmBookPostData.SealDateEnd = $("#DateToSealDate").val();
}
openWindowWithPost("/trade/BatchDownLoadDoc/", confirmBookPostData);
parent.layer.closeAll();
},
cancel: function (index, layero) {
parent.layer.closeAll();
},
success: function (layero, index) {
$(".btn-group").on("click", ".btn", function (event) {
$('input[name="docType"]:checked').prop("checked", false);
$(this).children("input").prop("checked", true);
});
}
});
}
function SendEmailHub() {
// 创建SignalR连接并连接到服务器上的Hub
var connection = new signalR.HubConnectionBuilder()
.withUrl('/tradeconfirm/sendemailhub')
.withAutomaticReconnect()
.build();
connection.start()
.then(function () {
$("#batchSendEmail").click(function () {
var jgrid = jQuery('#listGrid');
var rowIds = jgrid.jqGrid('getGridParam', 'selarrrow');
if (rowIds.length == 0) {
main.alert("请至少选择一笔交易"); return;
}
var contractCodes = [];
rowIds.forEach((v, i, arr) => {
var rowId = v;
var data = jgrid.jqGrid('getRowData', rowId);
contractCodes.push(data.ContractCode);
})
var req = {
contractCodes: contractCodes,
}
connection.invoke('StartProcessing', JSON.stringify(req));
main.waitMe(true);
});
}).catch(function (error) {
console.error(error);
});;
// 监听服务器发送的消息。
connection.on('UpdateProgress', function (msg) {
if (msg != null && msg != '') {
let jsonObject = JSON.parse(msg);
$("#email_result" + jsonObject.tradeId).text(jsonObject.send_email_result);
}
});
// 监听服务器发送的异常消息。
connection.on('ExceptionMessage', function (msg) {
if (msg.indexOf("正在发送邮件") < 0) {
main.waitMe(false);
SearchClick(true);
}
main.alert(msg);
});
// 监听服务器发送的完成消息。
connection.on('ProcessCompleted', function () {
main.alert("邮件发送处理完毕");
main.waitMe(false);
SearchClick(true);
});
// 监听连接关闭,启动重连
connection.onclose(async (error) => {
console.log("连接断开");
// 等待3秒后尝试重新连接
setTimeout(async () => {
try {
await connection.start();
console.log("已重新连接");
} catch (err) {
console.error("重新连接失败: ", err);
}
}, 3000); // 3秒
});
}
function openWindowWithPost(url, data) {
var form = document.createElement("form");
form.target = "_blank";
form.method = "POST";
form.action = url;
form.style.display = "none";
for (var key in data) {
if (data[key] instanceof Array) {
if (data[key].length === 0) {
var input = document.createElement("input");
input.type = "hidden";
input.name = key;
input.value = null;
form.appendChild(input);
}
else {
data[key].forEach((item, index, array) => {
var input = document.createElement("input");
input.type = "hidden";
input.name = key;
input.value = data[key][index];
form.appendChild(input);
});
}
}
else {
var input1 = document.createElement("input");
input1.type = "hidden";
input1.name = key;
input1.value = data[key];
form.appendChild(input1);
}
}
document.body.appendChild(form);
form.submit();
document.body.removeChild(form);
}