159 lines
6.6 KiB
C#
159 lines
6.6 KiB
C#
using YLErp.BLL;
|
|
using YLErp.Helpers;
|
|
using YLErp.Model;
|
|
using YLErp.Model.Enum;
|
|
|
|
namespace YLErp.Modules.TradeModule.DealModule
|
|
{
|
|
/// <summary>
|
|
/// 交易行权操作
|
|
/// </summary>
|
|
public class TradeExerciseService : TradeCashService
|
|
{
|
|
public TradeExerciseService(YLBaseService baseService) : base(baseService)
|
|
{
|
|
|
|
}
|
|
|
|
public TradeExerciseService(OptUserInfo userInfo) : base(userInfo)
|
|
{
|
|
}
|
|
|
|
/// <summary>
|
|
/// 行权待复核提交
|
|
/// </summary>
|
|
public TradeCashResult ApplyExerciseRecheck(TradeCashReq req)
|
|
{
|
|
var tradeDalService = new TradeDalModule.TradeDalService(this.OptUser);
|
|
//这个对象只提供收盘前数据,用于创建TradeCash记录
|
|
var td = tradeDalService.GetTradeOrEodTrade(new[] { req.TradeId }, req.ValueDate ?? SystemValueDate).FirstOrDefault();
|
|
if (td == null)
|
|
{
|
|
throw new ServiceException("交易信息不存在,id:" + req.TradeId);
|
|
}
|
|
var unwindNotional = td.IsUsePremiumRate == true ? req.UnwindPercentRate / 100 * td.OriginalNotional : req.UnwindNotional;
|
|
if (unwindNotional >= Math.Floor(td.Notional * Math.Pow(10, 8)) / Math.Pow(10, 8))
|
|
{
|
|
req.UnwindType = "全部行权";
|
|
td.UnWindNotional = td.Notional;
|
|
}
|
|
else
|
|
{
|
|
td.UnWindNotional = unwindNotional;
|
|
}
|
|
|
|
//部分行权和部分平仓业务处理保持一致
|
|
if (req.UnwindType == "部分行权")
|
|
{
|
|
return new TradeCloseService(this).CloseReCheck(req, true);
|
|
}
|
|
else
|
|
{
|
|
if (td == null)
|
|
{
|
|
throw new ServiceException("行权失败,该交易不存在,不能提交行权审核!");
|
|
}
|
|
if (PS.Config.TradeElement.ExecuteAfterGeneratedConfirmDoc && !td.HasGeneratedConfirmBook() && td.TradeType != "自定义交易")
|
|
{
|
|
throw new ServiceException("请先去生成交易确认书");
|
|
}
|
|
if (td.TradeStatus != ConsTrade.确认成交 && td.TradeStatus != ConsTrade.提前终止拒绝)
|
|
{
|
|
throw new ServiceException("行权失败,该交易处于待" + td.TradeStatus + "状态,不能提交行权审核!");
|
|
}
|
|
|
|
//保存tradecash
|
|
//增加现金交割交易记录
|
|
req.ValidState = ConsGlobal.InValid;
|
|
if (req.UnwindType != null && req.UnwindType.Contains("全部") && td.OriginalStockEqvNotional > 0)
|
|
{
|
|
req.UnwindPercentRate = td.StockEqvNotional / td.OriginalStockEqvNotional.Value * 100;
|
|
}
|
|
var valueDate = td.ExerciseDate != null && td.ExerciseDate < valuedateBLL.ValueDate ? td.ExerciseDate.Value : valuedateBLL.ValueDate;
|
|
var tc = ExerciseTrade_TradeCashSave(td, req, valueDate);
|
|
|
|
//检查是否有交易审批流程
|
|
var hasTradeProcess = HasTradeProcess();
|
|
ExerciseReCheck_SetTrade(req.TradeId, hasTradeProcess);
|
|
|
|
//配对 行权待复核提交
|
|
if (req.IsUnwindPairTrade)
|
|
{
|
|
//执行匹配交易
|
|
if (!string.IsNullOrEmpty(td.PairTrade))
|
|
{
|
|
int pairTradeId = Convert.ToInt32(td.PairTrade);
|
|
//这个对象只提供收盘前数据,用于创建TradeCash记录
|
|
var pairTrade = tradeDalService.GetTradeOrEodTrade(new[] { pairTradeId }, req.ValueDate.Value).FirstOrDefault();
|
|
req.ExtraAmount = Math.Abs(pairTrade.StockEqvNotional * (valuedateBLL.SystemDate.ExerciseCostRatioReal ?? 0)) * ("卖出".Equals(pairTrade.BuySell) ? 1 : 0);
|
|
req.Amount = CalcAmountOnly(pairTradeId, req.FinalPrice ?? 0) + req.ExtraAmount;
|
|
ExerciseTrade_TradeCashSave(pairTrade, req, valueDate);
|
|
|
|
ExerciseReCheck_SetTrade(pairTradeId, hasTradeProcess);
|
|
AddTradeOperationHistoryAndSetParentTradeInfo(false, pairTrade, "行权审核提交");
|
|
}
|
|
}
|
|
|
|
AddTradeOperationHistoryAndSetParentTradeInfo(false, td, "行权审核提交");
|
|
|
|
DbContext.SaveChanges();
|
|
|
|
return new TradeCashResult(td, tc);
|
|
}
|
|
}
|
|
|
|
private void ExerciseReCheck_SetTrade(int tradeId, bool hasTradeProcess)
|
|
{
|
|
var td = DbContext.trade.Find(tradeId);
|
|
td.OptDate = DateTime.Now;
|
|
td.CheckStatus = Convert.ToInt32(TradeCheckEnum.StatusOfOld);
|
|
|
|
// 先设状态,使流程类别能正确推断为 CloseProcess
|
|
td.TradeStatus = ConsTrade.行权待复核;
|
|
|
|
// 需求②:行权按交易状态查对应流程
|
|
var needApproval = valuedateBLL.SystemDate.CloseReApprove == 1 && TradeProcessCountByCategory(td) > 0;
|
|
if (needApproval)
|
|
{
|
|
// 需求①:进入审批前先判断触发条件——若所有节点都不满足触发条件,跳过审批。
|
|
needApproval = NeedApprovalByTrigger(td);
|
|
}
|
|
|
|
if (needApproval)
|
|
{
|
|
// 需要审批:保持"行权待复核",进入审批流程等待人工审批
|
|
InitTradeProcessOrder(td, UserId);
|
|
}
|
|
else
|
|
{
|
|
// 不需要审批:直接完成行权
|
|
td.ProcessOrderId = ProcessTradeLog.审批通过;
|
|
td.ProcessStatus = ProcessTradeStatus.通过审批.ToString();
|
|
td.ProcessOptDate = DateTime.Now;
|
|
DbContext.SaveChanges();
|
|
new TradeUnwindService(this).UnwindTrade(td, null, true, true);
|
|
return;
|
|
}
|
|
|
|
DbContext.SaveChanges();
|
|
}
|
|
|
|
//仅计算金额(业务未知,请知晓后重新注释)
|
|
private double? CalcAmountOnly(int enid, double tradePrice)
|
|
{
|
|
var td = DbContext.trade.Find(enid);
|
|
if (td != null)
|
|
{
|
|
tradeBLL.SetFieldsByTradeType(td);
|
|
var tc = new trade_cash
|
|
{
|
|
IsPossibleExec = true
|
|
};
|
|
BLL.EodSettlement.SettlementCalcCommons.SetPossibleExec(tc, td, tradePrice);
|
|
return tc.Amount;
|
|
}
|
|
return 0;
|
|
}
|
|
}
|
|
}
|