- 在 margin_template_v2 实体中新增 BookIds 字段存储适用簿记账户ID列表 - 实现簿记账户ID的规范化、解析和范围重叠判断逻辑 - 在客户端和默认模板编辑页面添加适用簿记账户选择控件 - 修改预付金模板解析逻辑以考虑簿记账户适用性 - 更新交易绑定模板验证以检查簿记账户范围匹配 - 优化模板冲突检测算法以支持簿记账户范围重叠验证 - 添加簿记账户ID存在性校验防止无效引用 - 实现前端动态筛选适用当前资产的模板选项
1499 lines
69 KiB
C#
1499 lines
69 KiB
C#
using Microsoft.EntityFrameworkCore.Storage;
|
|
using YLErp.BLL;
|
|
using YLErp.BLL.MarginCalculation;
|
|
using YLErp.Configuration;
|
|
using YLErp.CustomizedBizLogic;
|
|
using YLErp.DBModels.Consts;
|
|
using YLErp.DBModels.Helpers;
|
|
using YLErp.Enums;
|
|
using YLErp.Helpers;
|
|
using YLErp.Model.Enum;
|
|
using YLErp.Modules.SalesModule;
|
|
using YLErp.Modules.TagModule;
|
|
using YLErp.Modules.TradeModule.DealModule;
|
|
|
|
namespace YLErp.Modules.TradeModule.OrderModule
|
|
{
|
|
/// <summary>
|
|
/// 交易保存服务
|
|
/// </summary>
|
|
public class TradeSaveService : TradeServiceBase
|
|
{
|
|
TradeSourceEnum _source;
|
|
|
|
public TradeSaveService(OptUserInfo userInfo) : base(userInfo)
|
|
{
|
|
|
|
}
|
|
|
|
public TradeSaveService(YLBaseService baseService) : base(baseService)
|
|
{
|
|
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
public trade SaveTrade(trade req, TradeSourceEnum source, IDbContextTransaction trans = null)
|
|
{
|
|
if (req is null)
|
|
{
|
|
throw new ArgumentNullException(nameof(req));
|
|
}
|
|
|
|
_source = source;
|
|
|
|
var noTrans = trans == null;
|
|
|
|
try
|
|
{
|
|
if (noTrans)
|
|
{
|
|
trans = DbContext.Database.BeginTransaction();
|
|
}
|
|
|
|
//交易保存处理
|
|
var preHandler = new TradeSavePreHandler(this);
|
|
req = preHandler.Prepare(req, _source);
|
|
|
|
var dbTrade = preHandler.isAddNew
|
|
? InnerSaveNewTrade(req, preHandler.TradeNumberGenerated)
|
|
: (req.IsGroup == 1 && req.TradeType == "收益互换" ? InnerSaveEditSwapGroupTrade(req) : InnerSaveEditTrade(req, out var changeConfirmStatus));
|
|
|
|
//销售佣金数据处理
|
|
if (dbTrade.TradeType == "结构化交易")
|
|
{
|
|
foreach (var subTrade in req.SubTrades)
|
|
{
|
|
if (subTrade.SalesCommission != null)
|
|
{
|
|
subTrade.SalesCommission.ClientId = subTrade.ClientId;
|
|
if (PS.Config.ErpElement.SalesCommissionCalculation == "默认" || PS.Config.ErpElement.SalesCommissionCalculation == "" || PS.Config.ErpElement.SalesCommissionCalculation == null)
|
|
{
|
|
new SalesCommissionDataService(this).SaveTradeCommission(subTrade.id, subTrade.SalesCommission, false);
|
|
}
|
|
else if (PS.Config.ErpElement.SalesCommissionCalculation == "公式1")
|
|
{
|
|
if (req.SalesCommission?.SalesIds != null && req.SalesCommission.SalesIds.Any())
|
|
{
|
|
new SalesCommissionDetailDataService(this).SaveTradeCommissionDetail(subTrade.id, subTrade.SalesCommission.ClientId, subTrade.SalesCommission.Commission, subTrade.SalesCommission.CommissionFixed, subTrade.SalesCommission.SalesIds, false);
|
|
}
|
|
else
|
|
{
|
|
new SalesCommissionDetailDataService(this).RemoveTradeCommissionDetail(subTrade.id);
|
|
}
|
|
}
|
|
else { } //todo
|
|
|
|
}
|
|
|
|
if (dbTrade.StructureType == "折价" && PS.Config.Is国泰君安)
|
|
{
|
|
saveZheJiaTradeMarginTemplate(subTrade, dbTrade);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (req.SalesCommission != null)
|
|
{
|
|
req.SalesCommission.ClientId = dbTrade.ClientId;
|
|
}
|
|
if (PS.Config.ErpElement.SalesCommissionCalculation == "默认" || PS.Config.ErpElement.SalesCommissionCalculation == "" || PS.Config.ErpElement.SalesCommissionCalculation == null)
|
|
{
|
|
new SalesCommissionDataService(this).SaveTradeCommission(dbTrade.id, req.SalesCommission, false);
|
|
}
|
|
else if (PS.Config.ErpElement.SalesCommissionCalculation == "公式1")
|
|
{
|
|
if (req.SalesCommission?.SalesIds != null && req.SalesCommission.SalesIds.Any())
|
|
{
|
|
new SalesCommissionDetailDataService(this).SaveTradeCommissionDetail(dbTrade.id, req.SalesCommission.ClientId, req.SalesCommission.Commission, req.SalesCommission.CommissionFixed, req.SalesCommission.SalesIds, false);
|
|
}
|
|
else
|
|
{
|
|
new SalesCommissionDetailDataService(this).RemoveTradeCommissionDetail(dbTrade.id);
|
|
}
|
|
}
|
|
else { } //todo
|
|
}
|
|
|
|
//执行事务
|
|
if (noTrans)
|
|
{
|
|
trans.Commit();
|
|
}
|
|
|
|
return dbTrade;
|
|
}
|
|
finally
|
|
{
|
|
if (noTrans)
|
|
{
|
|
trans?.Dispose();
|
|
}
|
|
}
|
|
}
|
|
|
|
public trade SaveGroupTrade(OtcOptionTradeFull req, int[] tradeIds)
|
|
{
|
|
if (req.id > 0 && ConsTrade.TradeStatusAfterConfirmed.Contains(req.TradeStatus))
|
|
{
|
|
new TradeBackService(UserInfo).BackGroup(req.id, true, TradeBackActionEnum.EditMaturityDate);
|
|
}
|
|
|
|
var countRatio = (DataCacheProvider.GetUnderlyingDataSource().GetData(req.UnderlyingId)?.CountRatio) ?? 1;
|
|
|
|
if (req.IsUsePremiumRate == true)
|
|
{
|
|
req.Notional = req.SpotPrice != null && req.SpotPrice != 0 ? req.StockEqvNotional / req.SpotPrice.Value : 0;
|
|
req.TradeAmount = req.Notional / countRatio;
|
|
}
|
|
else
|
|
{
|
|
req.Notional = req.TradeAmount * countRatio;
|
|
req.StockEqvNotional = req.Notional * req.SpotPrice ?? 0;
|
|
}
|
|
req.PremiumRate = req.StockEqvNotional != 0 ? (req.TradePrice ?? 0) / req.StockEqvNotional : 0;
|
|
req.TradeSinglePrice = req.Notional != 0 ? (req.TradePrice ?? 0) / req.Notional : 0;
|
|
|
|
var dbTrade = TradeConverter.ConvertOptionTrade(req);
|
|
dbTrade.StartDate = dbTrade.TradeDate;
|
|
dbTrade.SettlementDate = dbTrade.ExerciseDate;
|
|
|
|
dbTrade.OriginalNotional = dbTrade.Notional;
|
|
dbTrade.OriginalStockEqvNotional = dbTrade.StockEqvNotional;
|
|
dbTrade.StockEqvNotionalMax = dbTrade.StockEqvNotional;
|
|
dbTrade.StockEqvNotionalReal = TradeHelper.GetStockEqvNotionalReal(dbTrade.StockEqvNotional, dbTrade.ParticipationRate, dbTrade.AnnualizeFactor);
|
|
|
|
if (req.id > 0)
|
|
{
|
|
var trade = DbContext.trade.AsNoTracking().FirstOrDefault(x => x.id == req.id);
|
|
if (trade == null)
|
|
{
|
|
throw new ServiceException($"该交易不存在");
|
|
}
|
|
|
|
var isDiffStructureType = trade.StructureType != req.StructureType;
|
|
|
|
trade.SpotPrice = req.SpotPrice;
|
|
trade.ExerciseDate = dbTrade.ExerciseDate;
|
|
trade.SettlementDate = dbTrade.ExerciseDate;
|
|
trade.BuySell = dbTrade.BuySell;
|
|
trade.IsUsePremiumRate = dbTrade.IsUsePremiumRate;
|
|
trade.TradeAmount = dbTrade.TradeAmount;
|
|
trade.Notional = dbTrade.Notional;
|
|
trade.OriginalNotional = dbTrade.OriginalNotional;
|
|
trade.StockEqvNotional = dbTrade.StockEqvNotional;
|
|
trade.OriginalStockEqvNotional = dbTrade.OriginalStockEqvNotional;
|
|
trade.StockEqvNotionalReal = dbTrade.StockEqvNotionalReal;
|
|
trade.TradeSinglePrice = dbTrade.TradeSinglePrice;
|
|
trade.PremiumRate = dbTrade.PremiumRate;
|
|
trade.TradePrice = dbTrade.TradePrice;
|
|
trade.IsMoneynessOption = dbTrade.IsMoneynessOption;
|
|
trade.StructureType = dbTrade.StructureType;
|
|
trade.Strike = dbTrade.Strike;
|
|
trade.AssetId = dbTrade.AssetId;
|
|
trade.AssetBookName = dbTrade.AssetBookName;
|
|
trade.TraderId = dbTrade.TraderId;
|
|
trade.TraderName = dbTrade.TraderName;
|
|
trade.Comments = dbTrade.Comments;
|
|
trade.StockEqvNotionalMax = dbTrade.StockEqvNotionalMax;
|
|
if (trade.StructureType == "气囊结构")
|
|
{
|
|
trade.ExtendInfo = null;
|
|
trade.trade_airbag = dbTrade.trade_airbag;
|
|
trade.OptionType = dbTrade.OptionType;
|
|
}
|
|
else
|
|
{
|
|
trade.ExtendInfo = dbTrade.ExtendInfo;
|
|
}
|
|
|
|
if (DbContext.trade.Any(n => n.TradeNumber == req.TradeNumber && n.id != req.id))
|
|
{
|
|
throw new ServiceException($"交易编号'{req.TradeNumber}'已经存在");
|
|
}
|
|
else if (PS.Config.ErpElement.UpperTradeNumber)
|
|
{
|
|
trade.TradeNumber = req.TradeNumber.ToUpperInvariant();
|
|
}
|
|
trade.MetaDic = dbTrade.MetaDic;
|
|
InnerSaveEditTrade(trade, out var changeConfirmStatus);
|
|
|
|
var subTrades = DbContext.trade.Where(x => x.ParentTradeId == trade.id).ToList();
|
|
subTrades.ForEach(x =>
|
|
{
|
|
x.StructureType = trade.StructureType;
|
|
if (dbTrade.StructureType == "折价" && isDiffStructureType && PS.Config.Is国泰君安)
|
|
{
|
|
saveZheJiaTradeMarginTemplate(x, dbTrade);
|
|
}
|
|
});
|
|
|
|
DbContext.SaveChanges();
|
|
|
|
SaveTradeOperationHistory(trade, "修改组合交易");
|
|
|
|
using (var tagService = new TagService(OptUser))
|
|
{
|
|
tagService.SetTradeTagForTradeEdit(new TagModule.Dto.SetTradeTagForTradeEditRequest
|
|
{
|
|
TradeId = trade.id,
|
|
Tags = req.Tags
|
|
});
|
|
}
|
|
|
|
return trade;
|
|
}
|
|
else if (tradeIds == null || !tradeIds.Any())
|
|
{
|
|
throw new ServiceException("缺少子交易");
|
|
}
|
|
else
|
|
{
|
|
SetDBModelCreator(dbTrade);
|
|
DbContext.trade.Add(dbTrade);
|
|
|
|
dbTrade.TradeStatus = ConsTrade.新增待确认;
|
|
dbTrade.TradeSource = _source.ToString();
|
|
dbTrade.TradeType = "结构化交易";
|
|
dbTrade.IsGroup = 1;
|
|
|
|
var copyLeg = DbContext.trade.Where(x => tradeIds.Contains(x.id) && x.UnderlyingId > 0).First();
|
|
//dbTrade.MetaDic = new TradeMetaService(this).GetTradeMeta(copyLeg.id);
|
|
dbTrade.UnderlyingCode = copyLeg.UnderlyingCode;
|
|
if (!string.IsNullOrEmpty(dbTrade.UnderlyingCode))
|
|
{
|
|
var preHandler = new TradeSavePreHandler(this);
|
|
preHandler.PrepareUnderlying(dbTrade, false);
|
|
}
|
|
dbTrade.SpotPrice = copyLeg.SpotPrice;
|
|
|
|
dbTrade.ParticipationRate = 1;
|
|
dbTrade.CreateDate = DateTime.Now;
|
|
|
|
if (string.IsNullOrWhiteSpace(req.TradeNumber) && req.id == 0)
|
|
{
|
|
dbTrade.TradeNumber = BizLogicSingleton.Instance.GenerateTradeNumberBeforeConfirm(dbTrade, DbContext);
|
|
|
|
//没有期货报送成交编号添加到dictionary,有则修改该key的值
|
|
if (PS.Config.Is招证)
|
|
{
|
|
if (req.MetaDic == null)
|
|
{
|
|
req.MetaDic = new Dictionary<string, string>();
|
|
}
|
|
if (dbTrade.MetaDic == null)
|
|
{
|
|
dbTrade.MetaDic = new Dictionary<string, string>();
|
|
|
|
}
|
|
|
|
req.MetaDic["期货报送成交编号"] = dbTrade.TradeNumber;
|
|
dbTrade.MetaDic["期货报送成交编号"] = dbTrade.TradeNumber;
|
|
}
|
|
|
|
}
|
|
else if (DbContext.trade.Any(n => n.TradeNumber == req.TradeNumber && n.id != req.id))
|
|
{
|
|
throw new ServiceException($"交易编号'{req.TradeNumber}'已经存在");
|
|
}
|
|
else if (PS.Config.ErpElement.UpperTradeNumber)
|
|
{
|
|
dbTrade.TradeNumber = req.TradeNumber.ToUpperInvariant();
|
|
}
|
|
|
|
DbContext.SaveChanges();
|
|
|
|
//交易元数据
|
|
if (req.MetaDic.Any())
|
|
{
|
|
foreach (var kv in req.MetaDic)
|
|
{
|
|
if (!string.IsNullOrEmpty(kv.Value))
|
|
{
|
|
AddTradeMeta(true, dbTrade.id, kv.Key, kv.Value);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
new TradeSaveExtend(this, true).Save(dbTrade, dbTrade);
|
|
|
|
var subTrades = DbContext.trade.Where(x => tradeIds.Contains(x.id)).ToList();
|
|
subTrades.ForEach(x =>
|
|
{
|
|
x.IsGroup = 2;
|
|
x.ParentTradeId = dbTrade.id;
|
|
x.StructureType = dbTrade.StructureType;
|
|
|
|
if (dbTrade.StructureType == "折价" && PS.Config.Is国泰君安)
|
|
{
|
|
saveZheJiaTradeMarginTemplate(x, dbTrade);
|
|
}
|
|
});
|
|
using (var tagService = new TagService(OptUser))
|
|
{
|
|
tagService.SetTradeTagForTradeEdit(new TagModule.Dto.SetTradeTagForTradeEditRequest
|
|
{
|
|
TradeId = dbTrade.id,
|
|
Tags = req.Tags
|
|
});
|
|
//subTrades.ForEach(d =>
|
|
//{
|
|
// tagService.SetTradeTagForTradeEdit(new TagModule.Dto.SetTradeTagForTradeEditRequest
|
|
// {
|
|
// TradeId = d.id,
|
|
// Tags = req.Tags
|
|
// });
|
|
//});
|
|
}
|
|
|
|
var subCashs = DbContext.ClientCashInCashOut.Where(x => x.TradeId != null && tradeIds.Contains(x.TradeId.Value)).ToList();
|
|
subCashs.ForEach(x =>
|
|
{
|
|
x.IsGroup = 2;
|
|
x.ParentTradeNumber = dbTrade.TradeNumber;
|
|
});
|
|
|
|
DbContext.SaveChanges();
|
|
|
|
SaveTradeOperationHistory(dbTrade, "新增组合交易");
|
|
|
|
var eodTrades = DbContext.eod_trade.Where(x => tradeIds.Contains(x.TradeId));
|
|
DbContext.eod_trade.RemoveRange(eodTrades);
|
|
DbContext.SaveChanges();
|
|
|
|
return dbTrade;
|
|
}
|
|
}
|
|
|
|
//新增交易保存
|
|
private trade InnerSaveNewTrade(trade req, bool tradeNumberGenerated)
|
|
{
|
|
if (req.ParentTradeId > 0 && req.TradeType == "收益互换")
|
|
{
|
|
var parentTrade = DbContext.trade.Find(req.ParentTradeId);
|
|
if (parentTrade != null && parentTrade.TradeType == "收益互换")
|
|
{
|
|
parentTrade.OriginalStockEqvNotional += req.StockEqvNotional;
|
|
parentTrade.StockEqvNotional += req.StockEqvNotional;
|
|
parentTrade.StockEqvNotionalReal += req.StockEqvNotional;
|
|
var tradePrice = (parentTrade.TradePrice ?? 0) * (parentTrade.BuySell == "买入" ? -1 : 1) + (req.TradePrice ?? 0) * (req.BuySell == "买入" ? -1 : 1);
|
|
parentTrade.TradePrice = Math.Abs(tradePrice);
|
|
parentTrade.BuySell = tradePrice >= 0 ? "卖出" : "买入";
|
|
}
|
|
}
|
|
|
|
var dbTrade = req.Clone();
|
|
dbTrade.trade_swap = req.trade_swap.Clone();
|
|
//if (double.IsNaN(dbTrade.TradeSinglePrice.Value)) dbTrade.TradeSinglePrice = 0;
|
|
//if (double.IsNaN(dbTrade.PremiumRate.Value)) dbTrade.PremiumRate = 0;
|
|
SetDBModelCreator(dbTrade);
|
|
DbContext.trade.Add(dbTrade);
|
|
|
|
//申万交易编号特殊处理(如果交易编号是用户手动输入时)
|
|
if (!tradeNumberGenerated && PS.Config.Is申万)
|
|
{
|
|
var client = DataCacheProvider.GetClientDataSource().GetData(dbTrade.ClientId);
|
|
if (client?.Code != null && dbTrade.TradeNumber.StartsWith(client.Code))
|
|
{
|
|
var canParseInt = int.TryParse(dbTrade.TradeNumber.Substring(client.Code.Length), out var contractNo);
|
|
if (canParseInt && contractNo > (client.CurrentContractNo ?? 0))
|
|
{
|
|
client.CurrentContractNo = contractNo;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (req.TradeType == "收益互换" && req.IsGroup == 1)
|
|
{
|
|
InnerSaveTrade2(true, dbTrade, dbTrade, true);
|
|
|
|
if (req.get_trade_swap_details.Any())
|
|
{
|
|
var index = 1;
|
|
foreach (var detail in dbTrade.get_trade_swap_details)
|
|
{
|
|
var trade = req.Clone();
|
|
trade.get_trade_swap_details = new List<trade_swap_detail>();
|
|
trade.trade_swap = req.trade_swap.Clone();
|
|
if (!string.IsNullOrEmpty(detail.UnderlyingCode))
|
|
{
|
|
var preHandler = new TradeSavePreHandler(this);
|
|
trade.UnderlyingCode = detail.UnderlyingCode;
|
|
var underlying = preHandler.PrepareUnderlying(trade, false);
|
|
|
|
trade.trade_swap.SwapType = "普通";
|
|
trade.trade_swap.OriginalTradeId = dbTrade.id;
|
|
if (trade.trade_swap.IsPayFloatingProfit)
|
|
{
|
|
trade.trade_swap.GetTradePrice = detail.TradePrice;
|
|
}
|
|
else
|
|
{
|
|
trade.trade_swap.PayTradePrice = detail.TradePrice;
|
|
}
|
|
trade.trade_swap.GetLongShort = detail.LongShort;
|
|
trade.trade_swap.GetUnderlyingCode = detail.UnderlyingCode;
|
|
trade.trade_swap.GetUnderlyingId = trade.UnderlyingId;
|
|
trade.trade_swap.GetSpotPrice = detail.SpotPrice;
|
|
trade.trade_swap.GetNotional = detail.Notional;
|
|
trade.trade_swap.GetTradeAmount = trade.trade_swap.GetNotional / underlying.CountRatio;
|
|
trade.BuySell = (trade.trade_swap.GetTradePrice ?? 0) - (trade.trade_swap.PayTradePrice ?? 0) == 0 ? (trade.trade_swap.IsPayFloatingProfit ? "卖出" : "买入") : ((trade.trade_swap.GetTradePrice ?? 0) - (trade.trade_swap.PayTradePrice ?? 0) > 0 ? "卖出" : "买入");
|
|
trade.TradePrice = Math.Abs((trade.trade_swap.GetTradePrice ?? 0) - (trade.trade_swap.PayTradePrice ?? 0));
|
|
trade.OriginalNotional = detail.Notional;
|
|
trade.Notional = detail.Notional ?? 0;
|
|
trade.TradeAmount = trade.trade_swap.GetTradeAmount ?? 0;
|
|
trade.SpotPrice = detail.SpotPrice;
|
|
trade.StockEqvNotionalReal = trade.Notional * trade.SpotPrice ?? 0;
|
|
trade.OriginalStockEqvNotional = trade.StockEqvNotionalReal;
|
|
trade.StockEqvNotional = trade.StockEqvNotionalReal;
|
|
trade.ParentTradeId = dbTrade.id;
|
|
trade.TradeNumber = BizLogicSingleton.Instance.GenerateSubTradeNumberBeforeConfirm(trade, dbTrade, index, DbContext);
|
|
index++;
|
|
trade.IsGroup = 2;
|
|
trade.TradeStatus = ConsTrade.新增待确认;
|
|
trade.TradeSource = req.TradeSource;
|
|
trade.Comments = null;
|
|
SetDBModelCreator(trade);
|
|
DbContext.trade.Add(trade);
|
|
DbContext.SaveChanges();
|
|
|
|
detail.ChildTradeId = trade.id;
|
|
|
|
InnerSaveTrade2(true, trade, trade, true);
|
|
}
|
|
}
|
|
}
|
|
else if (req.pay_trade_swap_details.Any())
|
|
{
|
|
var index = 1;
|
|
foreach (var detail in req.pay_trade_swap_details)
|
|
{
|
|
var trade = req.Clone();
|
|
trade.pay_trade_swap_details = new List<trade_swap_detail>();
|
|
trade.trade_swap = req.trade_swap.Clone();
|
|
if (!string.IsNullOrEmpty(detail.UnderlyingCode))
|
|
{
|
|
var preHandler = new TradeSavePreHandler(this);
|
|
trade.UnderlyingCode = detail.UnderlyingCode;
|
|
var underlying = preHandler.PrepareUnderlying(trade, false);
|
|
|
|
trade.trade_swap.SwapType = "普通";
|
|
trade.trade_swap.OriginalTradeId = dbTrade.id;
|
|
if (trade.trade_swap.IsPayFloatingProfit)
|
|
{
|
|
trade.trade_swap.GetTradePrice = detail.TradePrice;
|
|
}
|
|
else
|
|
{
|
|
trade.trade_swap.PayTradePrice = detail.TradePrice;
|
|
}
|
|
trade.trade_swap.PayLongShort = detail.LongShort;
|
|
trade.trade_swap.PayUnderlyingCode = detail.UnderlyingCode;
|
|
trade.trade_swap.PayUnderlyingId = trade.UnderlyingId;
|
|
trade.trade_swap.PaySpotPrice = detail.SpotPrice;
|
|
trade.trade_swap.PayNotional = detail.Notional;
|
|
trade.trade_swap.PayTradeAmount = trade.trade_swap.PayNotional / underlying.CountRatio;
|
|
trade.BuySell = (trade.trade_swap.GetTradePrice ?? 0) - (trade.trade_swap.PayTradePrice ?? 0) == 0 ? (trade.trade_swap.IsPayFloatingProfit ? "卖出" : "买入") : ((trade.trade_swap.GetTradePrice ?? 0) - (trade.trade_swap.PayTradePrice ?? 0) > 0 ? "卖出" : "买入");
|
|
trade.TradePrice = Math.Abs((trade.trade_swap.GetTradePrice ?? 0) - (trade.trade_swap.PayTradePrice ?? 0));
|
|
trade.OriginalNotional = detail.Notional;
|
|
trade.Notional = detail.Notional ?? 0;
|
|
trade.TradeAmount = trade.trade_swap.PayTradeAmount ?? 0;
|
|
trade.SpotPrice = detail.SpotPrice;
|
|
trade.StockEqvNotionalReal = trade.Notional * trade.SpotPrice ?? 0;
|
|
trade.OriginalStockEqvNotional = trade.StockEqvNotionalReal;
|
|
trade.StockEqvNotional = trade.StockEqvNotionalReal;
|
|
trade.ParentTradeId = dbTrade.id;
|
|
trade.TradeNumber = BizLogicSingleton.Instance.GenerateSubTradeNumberBeforeConfirm(trade, dbTrade, index, DbContext);
|
|
index++;
|
|
trade.IsGroup = 2;
|
|
trade.TradeStatus = ConsTrade.新增待确认;
|
|
trade.TradeSource = req.TradeSource;
|
|
SetDBModelCreator(trade);
|
|
DbContext.trade.Add(trade);
|
|
DbContext.SaveChanges();
|
|
|
|
detail.ChildTradeId = trade.id;
|
|
|
|
InnerSaveTrade2(true, trade, trade, true);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else if (req.TradeType == "结构化交易" && req.IsGroup == 1)
|
|
{
|
|
var copyLeg = dbTrade.SubTrades.Where(x => x.UnderlyingId > 0).First();
|
|
dbTrade.MetaDic = copyLeg.MetaDic;
|
|
dbTrade.UnderlyingCode = copyLeg.UnderlyingCode;
|
|
if (!string.IsNullOrEmpty(dbTrade.UnderlyingCode))
|
|
{
|
|
var preHandler = new TradeSavePreHandler(this);
|
|
preHandler.PrepareUnderlying(dbTrade, false);
|
|
}
|
|
dbTrade.SpotPrice = copyLeg.SpotPrice;
|
|
dbTrade.StartDate = dbTrade.TradeDate;
|
|
dbTrade.SettlementDate = dbTrade.ExerciseDate;
|
|
var countRatio = (DataCacheProvider.GetUnderlyingDataSource().GetData(copyLeg.UnderlyingId)?.CountRatio) ?? 1;
|
|
if (dbTrade.IsUsePremiumRate == true)
|
|
{
|
|
dbTrade.OriginalStockEqvNotional = dbTrade.StockEqvNotional;
|
|
dbTrade.StockEqvNotionalReal = dbTrade.StockEqvNotional;
|
|
dbTrade.Notional = dbTrade.SpotPrice != 0 ? dbTrade.StockEqvNotionalReal / dbTrade.SpotPrice.Value : 0;
|
|
dbTrade.OriginalNotional = dbTrade.Notional;
|
|
dbTrade.TradeAmount = dbTrade.Notional / countRatio;
|
|
dbTrade.TradeSinglePrice = dbTrade.Notional != 0 ? dbTrade.TradePrice / dbTrade.Notional : 0;
|
|
dbTrade.PremiumRate = dbTrade.StockEqvNotional > 0 ? dbTrade.TradePrice / dbTrade.StockEqvNotional : 0;
|
|
}
|
|
else
|
|
{
|
|
if (dbTrade.TradeAmount > 0)
|
|
{
|
|
dbTrade.Notional = dbTrade.TradeAmount * countRatio;
|
|
}
|
|
else
|
|
{
|
|
dbTrade.TradeAmount = dbTrade.Notional / countRatio;
|
|
}
|
|
dbTrade.OriginalNotional = dbTrade.Notional;
|
|
dbTrade.StockEqvNotionalReal = dbTrade.Notional * dbTrade.SpotPrice.Value;
|
|
dbTrade.StockEqvNotional = dbTrade.StockEqvNotionalReal;
|
|
dbTrade.OriginalStockEqvNotional = dbTrade.StockEqvNotional;
|
|
}
|
|
dbTrade.Notional = dbTrade.TradeAmount * countRatio;
|
|
dbTrade.OriginalNotional = dbTrade.Notional;
|
|
|
|
dbTrade.ParticipationRate = 1;
|
|
dbTrade.CreateDate = DateTime.Now;
|
|
DbContext.SaveChanges();
|
|
|
|
//交易元数据
|
|
if (dbTrade.MetaDic.Any())
|
|
{
|
|
foreach (var kv in dbTrade.MetaDic)
|
|
{
|
|
if (!string.IsNullOrEmpty(kv.Value))
|
|
{
|
|
AddTradeMeta(true, dbTrade.id, kv.Key, kv.Value);
|
|
}
|
|
}
|
|
}
|
|
|
|
new TradeSaveExtend(this, true).Save(dbTrade, dbTrade);
|
|
|
|
foreach (var subTrade in req.SubTrades)
|
|
{
|
|
if (!string.IsNullOrEmpty(subTrade.UnderlyingCode))
|
|
{
|
|
var preHandler = new TradeSavePreHandler(this);
|
|
preHandler.PrepareUnderlying(subTrade, false);
|
|
}
|
|
|
|
subTrade.ParentTradeId = dbTrade.id;
|
|
subTrade.IsGroup = 2;
|
|
subTrade.TradeStatus = ConsTrade.新增待确认;
|
|
subTrade.TradeSource = dbTrade.TradeSource;
|
|
subTrade.StructureType = dbTrade.StructureType;
|
|
SetDBModelCreator(subTrade);
|
|
DbContext.trade.Add(subTrade);
|
|
InnerSaveTrade2(true, subTrade, subTrade, true);
|
|
}
|
|
DbContext.TradeAuditLog.Add(new TradeAuditLog
|
|
{
|
|
TradeId = dbTrade.id,
|
|
Changes = string.Empty,
|
|
DataType = "00",
|
|
OptType = _source == TradeSourceEnum.导入交易 ? "导入交易" : "新增交易",
|
|
OptId = UserId,
|
|
OptName = UserName,
|
|
OptDate = OptDate,
|
|
AuditFlag = TradeAuditFlag.operation
|
|
});
|
|
DbContext.SaveChanges();
|
|
}
|
|
else if (req.TradeType == "结构化交易")
|
|
{
|
|
var tradeNumber = dbTrade.TradeNumber;
|
|
|
|
//将子交易复制到主交易
|
|
var copyLeg = dbTrade.SubTrades.First();
|
|
if (copyLeg.StructureType == "三领口组合")
|
|
{
|
|
copyLeg = dbTrade.SubTrades.Skip(1).First();
|
|
}
|
|
UpdateEntity(dbTrade, copyLeg);
|
|
|
|
dbTrade.TradeNumber = tradeNumber;
|
|
dbTrade.TradeType = "结构化交易";
|
|
dbTrade.ExerciseDate = req.SubTrades.Max(n => n.ExerciseDate ?? DateTime.MinValue);
|
|
DbContext.SaveChanges();
|
|
|
|
if (copyLeg.MetaDic.ContainsKey("合约编号"))
|
|
{
|
|
AddTradeMeta(false, dbTrade.id, "合约编号", copyLeg.MetaDic["合约编号"]);
|
|
}
|
|
|
|
foreach (var subTrade in dbTrade.SubTrades)
|
|
{
|
|
subTrade.ParentTradeId = dbTrade.id;
|
|
subTrade.IsGroup = 0;
|
|
SetDBModelCreator(subTrade);
|
|
DbContext.trade.Add(subTrade);
|
|
InnerSaveTrade2(true, subTrade, subTrade, true);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
InnerSaveTrade2(true, dbTrade, dbTrade, true);
|
|
}
|
|
|
|
return dbTrade;
|
|
}
|
|
|
|
private void saveZheJiaTradeMarginTemplate(trade subTrade, trade trade)
|
|
{
|
|
subTrade.InitialMargin = 0;
|
|
trade.InitialMargin = 0;
|
|
|
|
var marginTemplate = DbContext.margin_template_v2
|
|
.Where(x => x.Name == "无预付金")
|
|
.ToList()
|
|
.FirstOrDefault(x => x.IsApplicableToBook(subTrade.AssetId));
|
|
if (marginTemplate == null)
|
|
{
|
|
marginTemplate = new margin_template_v2()
|
|
{
|
|
Name = "无预付金",
|
|
MarginType = (int)MarginTypeV2Enum.单腿,
|
|
RuleType = (int)MarginRuleTypeEnum.无预付金,
|
|
TradeTypes = "香草期权,障碍期权,二元期权,亚式期权,彩虹期权,远期,双鲨期权,凤凰期权,雪球期权,气囊结构,收益互换,区间累积期权,合成价差期权,累计期权,自定义交易",
|
|
Comments = "预付金占用为零。",
|
|
IsDefault = false,
|
|
IsForClient = false,
|
|
IsValid = true,
|
|
BuySellType = BuySellEnum.All,
|
|
MarginScenarios = MarginScenarioEnum.All,
|
|
OptDate = DateTime.Now,
|
|
OptId = UserId,
|
|
OptName = UserName
|
|
};
|
|
DbContext.margin_template_v2.Add(marginTemplate);
|
|
DbContext.SaveChanges();
|
|
}
|
|
|
|
var tradeMarginTemplates = DbContext.trade_margin_template.Where(x => x.TradeId == subTrade.id);
|
|
DbContext.trade_margin_template.RemoveRange(tradeMarginTemplates);
|
|
var tradeMarginTemplate = new trade_margin_template()
|
|
{
|
|
TradeId = subTrade.id,
|
|
ValueDate = new DateTime(2000, 1, 1),
|
|
MarginTemplateId = marginTemplate.id,
|
|
IsLatest = true,
|
|
OptId = UserId,
|
|
OptName = UserName,
|
|
OptDate = DateTime.Now
|
|
};
|
|
DbContext.trade_margin_template.Add(tradeMarginTemplate);
|
|
DbContext.SaveChanges();
|
|
}
|
|
|
|
private trade InnerSaveEditSwapGroupTrade(trade req)
|
|
{
|
|
var details = req.get_trade_swap_details.Union(req.pay_trade_swap_details);
|
|
if (req.get_trade_swap_details.Any())
|
|
{
|
|
req.trade_swap.PayTradePrice = req.get_trade_swap_details.Sum(x => x.TradePrice ?? 0);
|
|
}
|
|
else if (req.pay_trade_swap_details.Any())
|
|
{
|
|
req.trade_swap.GetTradePrice = req.pay_trade_swap_details.Sum(x => x.TradePrice ?? 0);
|
|
}
|
|
var changeSwapDetails = false;
|
|
var tradeSwapDetails = DbContext.trade_swap_detail.Where(x => x.TradeId == req.id).ToList();
|
|
tradeSwapDetails.ForEach(x =>
|
|
{
|
|
var detail = details.FirstOrDefault(y => y.ChildTradeId == x.ChildTradeId);
|
|
if (detail == null)
|
|
{
|
|
changeSwapDetails = true;
|
|
}
|
|
else if (detail.UnderlyingCode != x.UnderlyingCode || detail.Notional != x.Notional || detail.SpotPrice != x.SpotPrice || detail.LongShort != x.LongShort || detail.TradePrice != x.TradePrice)
|
|
{
|
|
changeSwapDetails = true;
|
|
}
|
|
});
|
|
if (tradeSwapDetails.Count != details.Count())
|
|
{
|
|
changeSwapDetails = true;
|
|
}
|
|
|
|
//修改主交易信息
|
|
var dbTrade = InnerSaveEditTrade(req, out var changeConfirmStatus);
|
|
if (changeConfirmStatus)
|
|
{
|
|
changeSwapDetails = true;
|
|
}
|
|
|
|
if (changeSwapDetails)
|
|
{
|
|
//先删除子交易
|
|
var service = new TradeInvalidService(UserInfo);
|
|
var ids = new HashSet<int> { dbTrade.id };
|
|
var subTrades = DbContext.trade.Where(x => x.ParentTradeId == req.id && x.ValidState != "InValid").ToList();
|
|
var subTradeIds = subTrades.Select(x => x.id).ToList();
|
|
var swaps = DbContext.trade_swap.Where(x => subTradeIds.Contains(x.TradeId)).ToList();
|
|
int? originalTradeId = null;
|
|
foreach (var subTrade in subTrades)
|
|
{
|
|
var swap = swaps.FirstOrDefault(x => x.TradeId == subTrade.id);
|
|
if (swap != null && swap.OriginalTradeId > 0)
|
|
{
|
|
originalTradeId = swap.OriginalTradeId;
|
|
}
|
|
ids.Add(subTrade.id);
|
|
service.InnerInvalidTrade(subTrade);
|
|
}
|
|
service.SetCommissionInVaild(ids);
|
|
|
|
//重新生成子交易
|
|
if (req.get_trade_swap_details.Any())
|
|
{
|
|
var index = 1;
|
|
foreach (var detail in req.get_trade_swap_details)
|
|
{
|
|
var trade = req.Clone();
|
|
trade.get_trade_swap_details = new List<trade_swap_detail>();
|
|
trade.trade_swap = req.trade_swap.Clone();
|
|
trade.trade_swap.OriginalTradeId = originalTradeId ?? dbTrade.id;
|
|
if (!string.IsNullOrEmpty(detail.UnderlyingCode))
|
|
{
|
|
var preHandler = new TradeSavePreHandler(this);
|
|
trade.UnderlyingCode = detail.UnderlyingCode;
|
|
var underlying = preHandler.PrepareUnderlying(trade, false);
|
|
|
|
trade.trade_swap.SwapType = "普通";
|
|
if (trade.trade_swap.IsPayFloatingProfit)
|
|
{
|
|
trade.trade_swap.GetTradePrice = detail.TradePrice;
|
|
}
|
|
else
|
|
{
|
|
trade.trade_swap.PayTradePrice = detail.TradePrice;
|
|
}
|
|
trade.trade_swap.GetLongShort = detail.LongShort;
|
|
trade.trade_swap.GetUnderlyingCode = detail.UnderlyingCode;
|
|
trade.trade_swap.GetUnderlyingId = trade.UnderlyingId;
|
|
trade.trade_swap.GetSpotPrice = detail.SpotPrice;
|
|
trade.trade_swap.GetNotional = detail.Notional;
|
|
trade.trade_swap.GetTradeAmount = trade.trade_swap.GetNotional / underlying.CountRatio;
|
|
trade.BuySell = (trade.trade_swap.GetTradePrice ?? 0) - (trade.trade_swap.PayTradePrice ?? 0) == 0 ? (trade.trade_swap.IsPayFloatingProfit ? "卖出" : "买入") : ((trade.trade_swap.GetTradePrice ?? 0) - (trade.trade_swap.PayTradePrice ?? 0) > 0 ? "卖出" : "买入");
|
|
trade.TradePrice = Math.Abs((trade.trade_swap.GetTradePrice ?? 0) - (trade.trade_swap.PayTradePrice ?? 0));
|
|
trade.OriginalNotional = detail.Notional;
|
|
trade.Notional = detail.Notional ?? 0;
|
|
trade.TradeAmount = trade.trade_swap.GetTradeAmount ?? 0;
|
|
trade.SpotPrice = detail.SpotPrice;
|
|
trade.StockEqvNotionalReal = trade.Notional * trade.SpotPrice ?? 0;
|
|
trade.OriginalStockEqvNotional = trade.StockEqvNotionalReal;
|
|
trade.StockEqvNotional = trade.StockEqvNotionalReal;
|
|
trade.ParentTradeId = dbTrade.id;
|
|
trade.TradeNumber = BizLogicSingleton.Instance.GenerateSubTradeNumberBeforeConfirm(trade, dbTrade, index, DbContext);
|
|
index++;
|
|
trade.IsGroup = 2;
|
|
trade.TradeStatus = ConsTrade.新增待确认;
|
|
trade.TradeSource = req.TradeSource;
|
|
trade.Comments = null;
|
|
SetDBModelCreator(trade);
|
|
DbContext.trade.Add(trade);
|
|
DbContext.SaveChanges();
|
|
|
|
detail.ChildTradeId = trade.id;
|
|
|
|
InnerSaveTrade2(true, trade, trade, true);
|
|
}
|
|
}
|
|
}
|
|
else if (req.pay_trade_swap_details.Any())
|
|
{
|
|
var index = 1;
|
|
foreach (var detail in req.pay_trade_swap_details)
|
|
{
|
|
var trade = req.Clone();
|
|
trade.pay_trade_swap_details = new List<trade_swap_detail>();
|
|
trade.trade_swap = req.trade_swap.Clone();
|
|
trade.trade_swap.OriginalTradeId = originalTradeId ?? dbTrade.id;
|
|
if (!string.IsNullOrEmpty(detail.UnderlyingCode))
|
|
{
|
|
var preHandler = new TradeSavePreHandler(this);
|
|
trade.UnderlyingCode = detail.UnderlyingCode;
|
|
var underlying = preHandler.PrepareUnderlying(trade, false);
|
|
|
|
trade.trade_swap.SwapType = "普通";
|
|
if (trade.trade_swap.IsPayFloatingProfit)
|
|
{
|
|
trade.trade_swap.GetTradePrice = detail.TradePrice;
|
|
}
|
|
else
|
|
{
|
|
trade.trade_swap.PayTradePrice = detail.TradePrice;
|
|
}
|
|
trade.trade_swap.PayLongShort = detail.LongShort;
|
|
trade.trade_swap.PayUnderlyingCode = detail.UnderlyingCode;
|
|
trade.trade_swap.PayUnderlyingId = trade.UnderlyingId;
|
|
trade.trade_swap.PaySpotPrice = detail.SpotPrice;
|
|
trade.trade_swap.PayNotional = detail.Notional;
|
|
trade.trade_swap.PayTradeAmount = trade.trade_swap.PayNotional / underlying.CountRatio;
|
|
trade.BuySell = (trade.trade_swap.GetTradePrice ?? 0) - (trade.trade_swap.PayTradePrice ?? 0) == 0 ? (trade.trade_swap.IsPayFloatingProfit ? "卖出" : "买入") : ((trade.trade_swap.GetTradePrice ?? 0) - (trade.trade_swap.PayTradePrice ?? 0) > 0 ? "卖出" : "买入");
|
|
trade.TradePrice = Math.Abs((trade.trade_swap.GetTradePrice ?? 0) - (trade.trade_swap.PayTradePrice ?? 0));
|
|
trade.OriginalNotional = detail.Notional;
|
|
trade.Notional = detail.Notional ?? 0;
|
|
trade.TradeAmount = trade.trade_swap.PayTradeAmount ?? 0;
|
|
trade.SpotPrice = detail.SpotPrice;
|
|
trade.StockEqvNotionalReal = trade.Notional * trade.SpotPrice ?? 0;
|
|
trade.OriginalStockEqvNotional = trade.StockEqvNotionalReal;
|
|
trade.StockEqvNotional = trade.StockEqvNotionalReal;
|
|
trade.ParentTradeId = dbTrade.id;
|
|
trade.TradeNumber = BizLogicSingleton.Instance.GenerateSubTradeNumberBeforeConfirm(trade, dbTrade, index, DbContext);
|
|
index++;
|
|
trade.IsGroup = 2;
|
|
trade.TradeStatus = ConsTrade.新增待确认;
|
|
trade.TradeSource = req.TradeSource;
|
|
SetDBModelCreator(trade);
|
|
DbContext.trade.Add(trade);
|
|
DbContext.SaveChanges();
|
|
|
|
detail.ChildTradeId = trade.id;
|
|
|
|
InnerSaveTrade2(true, trade, trade, true);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return dbTrade;
|
|
}
|
|
|
|
//修改交易保存
|
|
private trade InnerSaveEditTrade(trade req, out bool changeConfirmStatus)
|
|
{
|
|
var dbTrade = DbContext.trade.Find(req.id);
|
|
|
|
if (dbTrade == null)
|
|
{
|
|
throw new ServiceException("保存失败,数据不存在");
|
|
}
|
|
|
|
dbTrade.SalesCommission = new SalesCommissionDataService(OptUser).GetTradeCommissionInfo(dbTrade.id);
|
|
//默认都没填销售信息时,不影响交易状态变更,都赋值空,这样下面GetDataChanges就不会包含commission变更信息
|
|
if (dbTrade.SalesCommission?.SalesIds == null && req.SalesCommission?.SalesIds == null)
|
|
{
|
|
dbTrade.SalesCommission = null;
|
|
req.SalesCommission = null;
|
|
}
|
|
|
|
if (!ConsGlobal.IsValid(dbTrade.ValidState))
|
|
{
|
|
throw new NotSupportedException("不支持对已无效的交易进行修改:" + dbTrade.TradeNumber);
|
|
}
|
|
|
|
if (req.ParentTradeId > 0 && req.TradeType == "收益互换")
|
|
{
|
|
var parentTrade = DbContext.trade.Find(req.ParentTradeId);
|
|
if (parentTrade != null)
|
|
{
|
|
parentTrade.OriginalStockEqvNotional += req.StockEqvNotional - (dbTrade.OriginalStockEqvNotional ?? 0);
|
|
parentTrade.StockEqvNotional += req.StockEqvNotional - (dbTrade.OriginalStockEqvNotional ?? 0);
|
|
parentTrade.StockEqvNotionalReal += req.StockEqvNotional - (dbTrade.OriginalStockEqvNotional ?? 0);
|
|
var tradePrice = (parentTrade.TradePrice ?? 0) * (parentTrade.BuySell == "买入" ? -1 : 1) + (req.TradePrice ?? 0) * (req.BuySell == "买入" ? -1 : 1) - (dbTrade.TradePrice ?? 0) * (dbTrade.BuySell == "买入" ? -1 : 1);
|
|
parentTrade.TradePrice = Math.Abs(tradePrice);
|
|
parentTrade.BuySell = tradePrice >= 0 ? "卖出" : "买入";
|
|
}
|
|
}
|
|
else if (req.IsGroup == 2)
|
|
{
|
|
var parentTrade = DbContext.trade.Find(req.ParentTradeId);
|
|
if (parentTrade != null)
|
|
{
|
|
var tradePrice = (parentTrade.TradePrice ?? 0) * (parentTrade.BuySell == "买入" ? -1 : 1) + (req.TradePrice ?? 0) * (req.BuySell == "买入" ? -1 : 1) - (dbTrade.TradePrice ?? 0) * (dbTrade.BuySell == "买入" ? -1 : 1);
|
|
parentTrade.TradePrice = tradePrice * (parentTrade.BuySell == "买入" ? -1 : 1);
|
|
if (parentTrade.OriginalNotional != null && parentTrade.OriginalNotional != 0)
|
|
{
|
|
parentTrade.TradeSinglePrice = parentTrade.TradePrice / parentTrade.OriginalNotional;
|
|
}
|
|
if (parentTrade.OriginalStockEqvNotional != null && parentTrade.OriginalStockEqvNotional != 0)
|
|
{
|
|
parentTrade.PremiumRate = TradeHelper.GetPremiumRateByTradePrice(parentTrade.TradePrice, parentTrade.OriginalStockEqvNotional, parentTrade.ParticipationRate, parentTrade.PrincipalSum(), parentTrade.AnnualizeFactor, parentTrade.BuySell, parentTrade.TradeType, true);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (valuedateBLL.SystemDate.EditTradeNeedRemark)
|
|
{
|
|
req.MetaDic.TryGetValue("remark", out var remark);
|
|
req.MetaDic.Remove("remark");
|
|
//记录审核日志
|
|
DbContext.TradeAuditLog.Add(new TradeAuditLog
|
|
{
|
|
TradeId = dbTrade.id,
|
|
Changes = remark,
|
|
DataType = "00",
|
|
OptId = UserId,
|
|
OptName = UserName,
|
|
OptDate = OptDate,
|
|
OptType = "修改交易",
|
|
AuditFlag = TradeAuditFlag.operation
|
|
});
|
|
}
|
|
|
|
//if (PS.Config.ErpElement.SecuritiesEnvironment && string.IsNullOrWhiteSpace(req.Comments))
|
|
//{
|
|
// throw new ServiceException("保存失败,交易编辑时,备注为必填字段");
|
|
//}
|
|
|
|
//使用明确的IsUsePremiumRate布尔值
|
|
if (!req.IsUsePremiumRate.HasValue && dbTrade.IsUsePremiumRate.HasValue)
|
|
{
|
|
req.IsUsePremiumRate = false;
|
|
}
|
|
|
|
req.CalcFlag = dbTrade.CalcFlag;
|
|
|
|
var oldClientId = dbTrade.ClientId;
|
|
var oldTradeStatus = dbTrade.TradeStatus;
|
|
var tradeDateChanged = dbTrade.TradeDate != req.TradeDate;
|
|
|
|
//移除价格观察
|
|
if (dbTrade.UnderlyingId != req.UnderlyingId)
|
|
{
|
|
RemoveEntities<manually_trade_observation_price>(x => x.TradeId == req.id);
|
|
}
|
|
|
|
//移除观察日
|
|
if (dbTrade.TradeType == "凤凰期权")
|
|
{
|
|
RemoveEntities<autocall_observation>(x => x.TradeId == dbTrade.id);
|
|
}
|
|
|
|
//移除可能的TradeMeta中组合标的信息
|
|
RemoveEntities<TradeMeta>(x => x.TradeId == dbTrade.id && x.MetaKey.StartsWith(ConsTradeMetaKey.SyntheticUnderlying));
|
|
|
|
//交易编号调整
|
|
var canGenerateTradeNumber = false;
|
|
if (req.ValidState == "InValid")
|
|
{
|
|
if (!string.IsNullOrWhiteSpace(dbTrade.TradeNumber))
|
|
{
|
|
new TradeDocumentDataService(this).DeleteConfirmBook(dbTrade.id);
|
|
|
|
if (dbTrade.TradeNumber.StartsWith("CW"))
|
|
{
|
|
req.TradeNumber = dbTrade.TradeNumber.Replace("CW", "XX");
|
|
}
|
|
else // if (PS.Config.Is光大光子)
|
|
{
|
|
req.TradeNumber = dbTrade.TradeNumber.Insert(0, "XX");
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
canGenerateTradeNumber = string.IsNullOrWhiteSpace(req.TradeNumber);
|
|
if (canGenerateTradeNumber)
|
|
{
|
|
req.TradeNumber = dbTrade.TradeNumber;
|
|
}
|
|
}
|
|
|
|
req.ContractVersion = dbTrade.ContractVersion;
|
|
req.PairTrade = dbTrade.PairTrade;
|
|
req.CreateDate = dbTrade.CreateDate;
|
|
//确认成交状态的交易修改后变为原始标记
|
|
req.DividendDate = new DateTime(2000, 1, 1);
|
|
|
|
//记录交易变更信息
|
|
var changsStr = string.Empty;
|
|
changeConfirmStatus = true;
|
|
TradeAuditFlag auditFlag = 0;
|
|
tradeBLL.SetFieldsByTradeType(dbTrade);
|
|
|
|
if (req.TradeType == "障碍期权")
|
|
{
|
|
req.trade_barrier_option.KnockInOutNotional = dbTrade.trade_barrier_option.KnockInOutNotional;
|
|
req.trade_barrier_option.KnockInOutDate = dbTrade.trade_barrier_option.KnockInOutDate;
|
|
}
|
|
|
|
var changes = DataChangeHelper.GetDataChanges(dbTrade, req);
|
|
|
|
if (req.TradeType == "远期" && changes.Any())
|
|
{
|
|
changes = changes.Where(x => x[0] != "TradeSinglePrice" && x[0] != "TradeSinglePriceString").ToList();
|
|
foreach (var item in changes)
|
|
{
|
|
if (item[0] == "OptionType")
|
|
{
|
|
item[1] = "多头空头";
|
|
item[2] = item[2].Replace("看涨", "多头").Replace("看跌", "空头");
|
|
item[3] = item[3].Replace("看涨", "多头").Replace("看跌", "空头");
|
|
}
|
|
else if (item[0] == "TradePrice")
|
|
{
|
|
item[1] = "开仓总费用";
|
|
}
|
|
}
|
|
}
|
|
|
|
var dbTradeMeta = DbContext.TradeMeta.Where(a => a.TradeId == dbTrade.id).ToDictionary(a => a.MetaKey, b => b.MetaValue);
|
|
|
|
var changMetas = new List<List<string>>();
|
|
var keys = new string[] { "ExchangeRate", "交易场所", "清算机构", "主协议编号", "补充协议编号", "中央对手方清算", "中央清算平台", "交易平台", "收取周期", "支付周期", "敲入观察周期", "敲出观察周期" };
|
|
|
|
foreach (var key in keys)
|
|
{
|
|
bool isdbMeta = dbTradeMeta.TryGetValue(key, out string oldVal);
|
|
bool isreqMeta = req.MetaDic.TryGetValue(key, out string newVal);
|
|
if (!isdbMeta && !isreqMeta || oldVal == newVal || (string.IsNullOrWhiteSpace(oldVal) && string.IsNullOrWhiteSpace(newVal)))
|
|
{
|
|
continue;
|
|
}
|
|
var changeMeta = new List<string>() { "", key, oldVal, newVal };
|
|
changMetas.Add(changeMeta);
|
|
}
|
|
if (changMetas.Any())
|
|
{
|
|
changes.AddRange(changMetas);
|
|
}
|
|
changsStr = changes.ToJson();
|
|
TradeHelper2.ReduceTradeExt(dbTrade);
|
|
TradeHelper2.ReduceTradeExt(req);
|
|
if (dbTrade.TradeStatus != ConsTrade.新增待确认)
|
|
{
|
|
//var changes = TradeChangeUtil.GetAllChanges(dbTrade, req);
|
|
//changsStr = TradeChangeUtil.SerializeChanges(changes, out auditFlag);
|
|
if (PS.Config.Company == CompanyEnum.东莞)
|
|
{
|
|
changeConfirmStatus = changes.Any();
|
|
}
|
|
else
|
|
{
|
|
//修改备注和簿记不需要提交审核和审批
|
|
changeConfirmStatus = !changes.All(n => string.IsNullOrEmpty(n[0]) || n[0] == nameof(trade.Comments)
|
|
|| n[0] == nameof(trade.AssetId) || n[0] == nameof(trade.AssetBookName));
|
|
}
|
|
}
|
|
//记录审核日志
|
|
DbContext.TradeAuditLog.Add(new TradeAuditLog
|
|
{
|
|
TradeId = dbTrade.id,
|
|
Changes = changsStr,
|
|
DataType = "C02",
|
|
OptId = UserId,
|
|
OptName = UserName,
|
|
OptDate = OptDate,
|
|
OptType = "修改交易",
|
|
AuditFlag = TradeAuditFlag.operation | auditFlag
|
|
});
|
|
|
|
//清除累计期权换月设置
|
|
ClearAccumulatorChangeDatas(dbTrade, req);
|
|
|
|
//更新数据库实体
|
|
UpdateEntity(dbTrade, req);
|
|
//交易状态处理
|
|
if (dbTrade.CheckTradeUpdate == Convert.ToInt32(TradeCheckEnum.StatusOfNew) || dbTrade.TradeStatus == ConsTrade.确认成交)
|
|
{
|
|
if (changeConfirmStatus)
|
|
{
|
|
dbTrade.TradeStatus = ConsTrade.修改待确认;
|
|
dbTrade.CheckTradeUpdate = Convert.ToInt32(TradeCheckEnum.StatusOfOld);
|
|
dbTrade.CheckStatus = null;
|
|
}
|
|
}
|
|
else if (dbTrade.TradeStatus != ConsTrade.修改待确认)
|
|
{
|
|
dbTrade.TradeStatus = ConsTrade.新增待确认;
|
|
dbTrade.CheckTradeUpdate = Convert.ToInt32(TradeCheckEnum.StatusOfOld);
|
|
dbTrade.CheckStatus = null;
|
|
//如果是新增待确认并且修改了客户,需要重新生成交易编号
|
|
if (oldClientId != dbTrade.ClientId && canGenerateTradeNumber)
|
|
{
|
|
dbTrade.TradeNumber = BizLogicSingleton.Instance.GenerateTradeNumberBeforeConfirm(dbTrade, DbContext);
|
|
}
|
|
}
|
|
|
|
if (changeConfirmStatus)
|
|
{
|
|
if (dbTrade.TradeType == "障碍期权")
|
|
{
|
|
req.trade_barrier_option.KnockInOutNotional = null;
|
|
req.trade_barrier_option.KnockInOutDate = null;
|
|
req.trade_barrier_option.KnockInOutStatus = null;
|
|
}
|
|
else if (req.TradeType == "气囊结构")
|
|
{
|
|
req.trade_airbag.KnockInOutStatus = null;
|
|
req.trade_airbag.KnockInOutDate = null;
|
|
req.trade_airbag.KnockInOutNotional = null;
|
|
}
|
|
}
|
|
|
|
dbTrade.TradeOldStatus = oldTradeStatus;
|
|
|
|
//修改结构化交易父交易的状态
|
|
if (dbTrade.ParentTradeId > 0 && dbTrade.IsGroup == 0)
|
|
{
|
|
var parentTrade = DbContext.trade.FirstOrDefault(n => n.id == dbTrade.ParentTradeId);
|
|
if (parentTrade != null)
|
|
{
|
|
SetParentTrade(dbTrade, parentTrade);
|
|
//结构化交易子交易修改了交易编号的处理(需要用户自己规范交易编号,必须带有横杠分隔符)
|
|
if (!string.IsNullOrWhiteSpace(req.TradeNumber) && !req.TradeNumber.StartsWith(parentTrade.TradeNumber))
|
|
{
|
|
UpdateStructureTradeNumbers(parentTrade, dbTrade);
|
|
}
|
|
}
|
|
}
|
|
|
|
//配对交易数据同步修改
|
|
if (!string.IsNullOrWhiteSpace(dbTrade.PairTrade))
|
|
{
|
|
SetPairTrade(dbTrade);
|
|
}
|
|
|
|
//重置历史数据(20210928:如果是当天修改也支持重置)
|
|
var resetHisData = dbTrade.TradeStatus == "新增待确认" || tradeDateChanged || valuedateBLL.ValueDate == dbTrade.TradeDate;
|
|
if (resetHisData)
|
|
{
|
|
dbTrade.TradeSavedVol = PS.Config.Is厦门象屿 ? dbTrade.TradeCloseVolatility : dbTrade.TradeOpenVolatility;
|
|
if (PS.Config.ErpElement.VolMode == Configuration.VolModeEnum.VolSurface)
|
|
{
|
|
dbTrade.TradeSavedVol = dbTrade.Vol;
|
|
}
|
|
}
|
|
|
|
new ExtensionTimeService(UserInfo, DbContext).DelExtensionTime(dbTrade.id, DateTime.MinValue, false);
|
|
InnerSaveTrade2(false, dbTrade, req, resetHisData, changeConfirmStatus);
|
|
|
|
return dbTrade;
|
|
}
|
|
|
|
//用于交易(不能是结构化主交易)入库后续处理
|
|
//changeConfirmStatus:保存交易修改时需要
|
|
private void InnerSaveTrade2(bool isAddNew, trade dbTrade, trade req, bool resetHisData, bool changeConfirmStatus = false)
|
|
{
|
|
//System.Diagnostics.Debug.Assert(dbTrade.TradeType != "结构化交易");
|
|
|
|
//期初价格确认状态(20210720:等需要时再放开)
|
|
//SetInitialSpotPriceState(isAddNew, dbTrade);
|
|
|
|
//保存修改
|
|
DbContext.SaveChanges();
|
|
|
|
//扩展数据保存
|
|
new TradeSaveExtend(this, isAddNew).Save(req, dbTrade);
|
|
|
|
//保存历史数据(新增或交易状态为新增待确认或交易日期变更)
|
|
if (resetHisData)
|
|
{
|
|
SaveHisDataForNewTrade(dbTrade);
|
|
}
|
|
|
|
//交易元数据
|
|
if (req.MetaDic.Any())
|
|
{
|
|
foreach (var kv in req.MetaDic)
|
|
{
|
|
if (isAddNew)
|
|
{
|
|
if (!string.IsNullOrEmpty(kv.Value))
|
|
{
|
|
AddTradeMeta(false, dbTrade.id, kv.Key, kv.Value);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
AddOrUpdateTradeMeta(false, dbTrade.id, kv.Key, kv.Value);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (isAddNew)
|
|
{
|
|
var auditLog = new TradeAuditLog
|
|
{
|
|
TradeId = dbTrade.id,
|
|
Changes = string.Empty,
|
|
DataType = "00",
|
|
OptType = "新增交易",
|
|
OptId = UserId,
|
|
OptName = UserName,
|
|
OptDate = OptDate,
|
|
AuditFlag = TradeAuditFlag.operation
|
|
};
|
|
if (_source == TradeSourceEnum.导入交易)
|
|
{
|
|
auditLog.OptType = "导入交易";
|
|
}
|
|
//记录审核日志
|
|
DbContext.TradeAuditLog.Add(auditLog);
|
|
}
|
|
else if (changeConfirmStatus)
|
|
{
|
|
//删除交易确认书
|
|
new TradeDocumentDataService(this).DeleteBooksAfterEditTrade(dbTrade);
|
|
|
|
//保存客户资金
|
|
new ClientCashInCashOutService(this).SaveClientCashInCashOut(dbTrade);
|
|
|
|
//删除票息记录
|
|
DbContext.autocall_observation.RemoveRange(DbContext.autocall_observation.Where(n => n.TradeId == dbTrade.id));
|
|
}
|
|
|
|
//删除E/Bod_Trade记录(tradedate也可能会被修改)
|
|
//如果修改不需要修改确认状态,客户资金相关数据不删除
|
|
RemoveEodTradeAndFutureInfo(false, dbTrade.id, changeConfirmStatus ? DateTime.MinValue : DateTime.MaxValue, deleteOtherCashs: true);
|
|
|
|
if (dbTrade.InitialMargin == null && dbTrade.TradeType != "自定义交易" && dbTrade.TradeType != "结构化交易" && ((req.IsGroup != 1 && dbTrade.TradeType != "收益互换") || (req.IsGroup != 2 && dbTrade.TradeType == "收益互换")))
|
|
{
|
|
dbTrade.InitialMargin = MarginDefault.GetInitialMarginWithPreHandle(dbTrade);
|
|
}
|
|
|
|
DbContext.SaveChanges();
|
|
}
|
|
|
|
//配对交易数据同步修改
|
|
private void SetPairTrade(trade dbTrade)
|
|
{
|
|
var id = Convert.ToInt32(dbTrade.PairTrade);
|
|
var pairTrade = DbContext.trade.Find(id);
|
|
pairTrade.UnderlyingId = dbTrade.UnderlyingId;
|
|
pairTrade.UnderlyingCode = dbTrade.UnderlyingCode;
|
|
pairTrade.UnderlyingAssetClass = dbTrade.UnderlyingAssetClass;
|
|
pairTrade.UnderlyingAssetName = dbTrade.UnderlyingAssetName;
|
|
pairTrade.UnderlyingInstrumentType = dbTrade.UnderlyingInstrumentType;
|
|
pairTrade.BuySell = dbTrade.BuySell == "买入" ? "卖出" : "买入";
|
|
pairTrade.ExerciseMode = dbTrade.ExerciseMode;
|
|
pairTrade.OptionType = dbTrade.OptionType;
|
|
pairTrade.StartDate = dbTrade.StartDate;
|
|
pairTrade.ExerciseDate = dbTrade.ExerciseDate;
|
|
pairTrade.Strike = dbTrade.Strike;
|
|
pairTrade.StockEqvNotional = dbTrade.StockEqvNotional;
|
|
// 场内期权交易不应该有标的期初价格
|
|
pairTrade.SpotPrice = dbTrade.TradeType == "场内期权" ? null : dbTrade.SpotPrice;
|
|
pairTrade.Notional = dbTrade.Notional;
|
|
pairTrade.OriginalNotional = dbTrade.OriginalNotional;
|
|
pairTrade.OriginalStockEqvNotional = dbTrade.OriginalStockEqvNotional;
|
|
pairTrade.TradeAmount = dbTrade.TradeAmount;
|
|
pairTrade.TradePrice = pairTrade.PremiumRate == null || pairTrade.PremiumRate <= 0 ? pairTrade.TradePrice : (pairTrade.StockEqvNotional * pairTrade.PremiumRate);
|
|
pairTrade.TradeSinglePrice = TradeHelper.GetTradeSinglePriceByTradePrice(pairTrade.TradePrice, pairTrade.Notional, pairTrade.OriginalPrincipalSum, pairTrade.BuySell, pairTrade.TradeType, true);
|
|
}
|
|
|
|
//为新增交易保存历史数据(持仓平仓波动率、对冲波动率、分红率、无风险利率)
|
|
private void SaveHisDataForNewTrade(trade tr)
|
|
{
|
|
if (tr.id < 1)
|
|
{
|
|
throw new ServiceException("trade id不正确");
|
|
}
|
|
|
|
var valueDate = tr.TradeDate ?? DateTime.Today;
|
|
|
|
if (tr.TradeType != "远期" && tr.TradeType != "收益互换" && tr.TradeType != "现金流交易")
|
|
{
|
|
//----------------------------------
|
|
// trade_volatility
|
|
//----------------------------------
|
|
|
|
_ = RemoveEntities<TradeVolatility>(x => x.TradeId == tr.id);
|
|
|
|
if (PS.Config.ErpElement.VolMode == VolModeEnum.VolSurface)
|
|
{
|
|
tr.TradeSavedVol ??= tr.Vol;
|
|
tr.TradeOpenVolatility ??= tr.Vol;
|
|
tr.TradeCloseVolatility ??= tr.Vol;
|
|
tr.NumOfSmoothingDays = 1;
|
|
}
|
|
|
|
var tradVolatility = new TradeVolatility
|
|
{
|
|
TradeId = tr.id,
|
|
ValueDate = valueDate,
|
|
OptId = tr.OptId,
|
|
OptName = tr.OptName,
|
|
OptDate = DateTime.Now,
|
|
NumOfSmoothingDays = tr.NumOfSmoothingDays,
|
|
TradeCloseVolatility = tr.TradeCloseVolatility,
|
|
TradePositionVolatility = tr.TradeOpenVolatility,
|
|
IsFromTradeAdd = true
|
|
};
|
|
|
|
DbContext.TradeVolatility.Add(tradVolatility);
|
|
|
|
if (PS.Config.Company == Configuration.CompanyEnum.光大光子 && tradVolatility.TradePositionVolatility.HasValue
|
|
&& NumberHelper.TryParse(PS.Config.ErpElement.TradeOpenVolOff, out var d, out var isPercent) && d <= 1)
|
|
{
|
|
var openVol = tr.TradeOpenVolatility.Value;
|
|
|
|
//开仓波动率高于目标波动率,则减点,否则加点
|
|
var positionVol = openVol - (openVol - tr.TradeCloseVolatility.Value) * d;
|
|
|
|
//第一天使用折扣后的波动率(对冲+持仓)
|
|
tr.TradeSavedVol = tradVolatility.TradePositionVolatility = positionVol;
|
|
|
|
var clone = tradVolatility.Clone();
|
|
|
|
//第一天使用折扣后的波动率(不要平滑处理)
|
|
tradVolatility.NumOfSmoothingDays = 1;
|
|
tradVolatility.TradeCloseVolatility = positionVol;
|
|
|
|
//第一天之后使用平滑波动率
|
|
clone.ValueDate = QdpModule.QdpCalendarHelper.GetNonHoliday(tradVolatility.ValueDate.AddDays(1));
|
|
DbContext.TradeVolatility.Add(clone);
|
|
}
|
|
|
|
//----------------------------------
|
|
// trade_hedge_vol
|
|
//----------------------------------
|
|
|
|
_ = RemoveEntities<trade_hedge_vol>(x => x.TradeId == tr.id);
|
|
|
|
var hedgeTradeVol = new trade_hedge_vol
|
|
{
|
|
TradeId = tr.id,
|
|
ValueDate = valueDate,
|
|
OptId = tr.OptId,
|
|
OptName = tr.OptName,
|
|
OptDate = DateTime.Now,
|
|
TradeSavedVol = tr.TradeSavedVol ?? 0
|
|
};
|
|
DbContext.trade_hedge_vol.Add(hedgeTradeVol);
|
|
}
|
|
|
|
//----------------------------------
|
|
// trade_hisdata:NoRiskRate + DividendRate
|
|
//----------------------------------
|
|
|
|
RemoveEntities<TradeHisData>(x => x.TradeId == tr.id);
|
|
|
|
var hisDataNoRisk = new TradeHisData
|
|
{
|
|
TradeId = tr.id,
|
|
ValueDate = valueDate,
|
|
ValueType = ConsTradeField.NoRiskRate,
|
|
Value = tr.NoRiskRate ?? ((valuedateBLL.SystemDate.RiskFreeRate ?? 0) / 100),
|
|
OptId = tr.OptId,
|
|
OptName = tr.OptName,
|
|
OptDate = DateTime.Now
|
|
};
|
|
DbContext.TradeHisData.Add(hisDataNoRisk);
|
|
|
|
if (hisDataNoRisk.Value < 1e-5)
|
|
{
|
|
LogFactory.GetLogger(nameof(SaveHisDataForNewTrade)).Info($"[NoRiskRate]{tr.id}--{tr.NoRiskRate}--{valuedateBLL.SystemDate.RiskFreeRate}--{tr.OptName}");
|
|
}
|
|
|
|
if (tr.DividendRate.HasValue)
|
|
{
|
|
var hisDataDividendRate = new TradeHisData
|
|
{
|
|
TradeId = tr.id,
|
|
ValueDate = valueDate,
|
|
ValueType = ConsTradeField.DividendRate,
|
|
Value = tr.DividendRate.Value,
|
|
OptId = tr.OptId,
|
|
OptName = tr.OptName,
|
|
OptDate = DateTime.Now,
|
|
};
|
|
DbContext.TradeHisData.Add(hisDataDividendRate);
|
|
}
|
|
}
|
|
|
|
//结构化交易子交易修改了交易编号的处理
|
|
private void UpdateStructureTradeNumbers(trade parentTrade, trade saveTrade)
|
|
{
|
|
//浙期的子交易编号中不包含-,分腿编号是最后一位数字
|
|
var index = PS.Config.Company == Configuration.CompanyEnum.浙期 ? saveTrade.TradeNumber.Length - 1 : saveTrade.TradeNumber.LastIndexOf('-');
|
|
|
|
if (index < 1)
|
|
{
|
|
return;
|
|
}
|
|
//修改父交易的交易编号
|
|
parentTrade.TradeNumber = saveTrade.TradeNumber.Substring(0, index);
|
|
|
|
//修改兄弟交易的交易编号
|
|
var siblingTds = DbContext.trade.Where(n => n.id != saveTrade.id && n.ParentTradeId == parentTrade.id).ToArray();
|
|
|
|
foreach (var std in siblingTds)
|
|
{
|
|
index = PS.Config.Company == Configuration.CompanyEnum.浙期 ? std.TradeNumber.Length - 1 : std.TradeNumber.LastIndexOf('-');
|
|
|
|
if (index > 0)
|
|
{
|
|
std.TradeNumber = parentTrade.TradeNumber + std.TradeNumber.Substring(index);
|
|
}
|
|
}
|
|
}
|
|
|
|
//清除累计期权换月设置
|
|
private void ClearAccumulatorChangeDatas(trade dbTrade, trade req)
|
|
{
|
|
if (dbTrade.TradeType != "累计期权")
|
|
{
|
|
return;
|
|
}
|
|
|
|
var changed = dbTrade.TradeType != req.TradeType
|
|
|| dbTrade.TradeDate != req.TradeDate
|
|
|| dbTrade.ExerciseDate != req.ExerciseDate
|
|
|| dbTrade.Strike != req.Strike
|
|
|| dbTrade.UnderlyingCode != req.UnderlyingCode
|
|
|| dbTrade.trade_accumulator_option.PayoffType != req.trade_accumulator_option.PayoffType
|
|
|| dbTrade.trade_accumulator_option.KOBarrier != req.trade_accumulator_option.KOBarrier
|
|
|| dbTrade.trade_accumulator_option.KOObservationDates != req.trade_accumulator_option.KOObservationDates;
|
|
|
|
if (!changed)
|
|
{
|
|
return;
|
|
}
|
|
|
|
var actions = DbContext.TradeAction.Where(n => n.TradeId == dbTrade.id && n.IsValid && n.ActionType == TradeActionType.AccumulatorChange).ToArray();
|
|
|
|
foreach (var action in actions)
|
|
{
|
|
action.IsValid = false;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//从远期交易保存上拷贝而来,暂时备份看看是否有用
|
|
//if (dbTrade.CheckTradeUpdate == Convert.ToInt32(TradeCheckEnum.StatusOfNew))
|
|
//{
|
|
// dbTrade.TradeStatus = ConsTrade.修改待确认;
|
|
//}
|
|
//else
|
|
//{
|
|
// if (dbTrade.TradeStatus == ConsTrade.审批中)
|
|
// {
|
|
// dbTrade.ProcessOrderId = 1;
|
|
// dbTrade.ProcessOptDate = DateTime.Now;
|
|
// dbTrade.ProcessStatus = "审批中";
|
|
// dbTrade.TradeStatus = ConsTrade.新增待确认;
|
|
// }
|
|
// if (dbTrade.TradeStatus == ConsTrade.已拒绝)
|
|
// {
|
|
// if (dbTrade.CheckTradeUpdate == Convert.ToInt32(TradeCheckEnum.StatusOfNew))
|
|
// {
|
|
// dbTrade.TradeStatus = ConsTrade.修改待确认;
|
|
// }
|
|
// else
|
|
// {
|
|
// dbTrade.TradeStatus = ConsTrade.新增待确认;
|
|
// }
|
|
|
|
// dbTrade.ProcessOrderId = 0;
|
|
// dbTrade.ProcessOptDate = DateTime.Now;
|
|
// dbTrade.ProcessStatus = "未审批";
|
|
// }
|
|
//}
|