791 lines
35 KiB
C#
791 lines
35 KiB
C#
using BaseOUDAL;
|
||
using DocumentFormat.OpenXml.Office2013.Drawing.ChartStyle;
|
||
using Microsoft.EntityFrameworkCore.Query.SqlExpressions;
|
||
using OfficeOpenXml.FormulaParsing.ExpressionGraph;
|
||
using System.Linq;
|
||
using System.Linq.Expressions;
|
||
using YLErp.BLL.Eod;
|
||
using YLErp.DBModels;
|
||
using YLErp.Helpers;
|
||
using YLErp.Model.Enum;
|
||
using YLErp.Modules.TradeModule;
|
||
|
||
namespace YLErp.Modules.SystemModule
|
||
{
|
||
/// <summary>
|
||
/// 审批流程业务服务
|
||
/// </summary>
|
||
public class ApprovalProcessService : YLBaseService
|
||
{
|
||
public ApprovalProcessService(OptUserInfo optUser) : base(optUser)
|
||
{
|
||
}
|
||
|
||
/// <summary>
|
||
/// 添加审批流程(变更或删除)
|
||
/// </summary>
|
||
public int AddProcess(string type, List<ApprovalProcessAddRequest> data)
|
||
{
|
||
var clientQuery = DataCacheProvider.GetClientDataSource().AsQueryable();
|
||
|
||
var delList = DbContext.approvalprocess.Where(s => s.processType == type).ToArray();
|
||
|
||
DbContext.approvalprocess.RemoveRange(delList);
|
||
|
||
if (data != null && data.Count > 0)
|
||
{
|
||
data = data.OrderBy(s => s.Index).ToList();
|
||
|
||
var list = data.Select(item => new approvalprocess
|
||
{
|
||
processType = item.Type,
|
||
order = item.Index,
|
||
roleId = item.SelectValue,
|
||
ruleType = item.ApprovalRules,
|
||
approvalGroupId = item.approvalGroupId,
|
||
node = item.node,
|
||
parentNode = item.parentNode,
|
||
approvalCondition = item.approvalCondition,
|
||
conditionConfig = item.conditionConfig,
|
||
triggerCondition = item.triggerCondition
|
||
}).ToList();
|
||
|
||
DbContext.approvalprocess.AddRange(list);
|
||
}
|
||
|
||
if (type == "OpenProcess")
|
||
{
|
||
List<string> optTypes = new List<string>() { "提交开户审批", "重新提交开户审批" };
|
||
var clients = GetClients(optTypes);
|
||
if (data == null || data.Count == 0)
|
||
{
|
||
if (clients != null && clients.Count > 0)
|
||
{
|
||
throw new ServiceException("有用户在审批中,不能删除审批流程!");
|
||
}
|
||
}
|
||
else
|
||
{
|
||
ChangeClientProcess(data, clients, delList);
|
||
}
|
||
}
|
||
else if (type == "TradeProcess")
|
||
{
|
||
|
||
if (data != null && data.Count > 0)
|
||
{
|
||
ChangeTradeProcess(data, delList);
|
||
}
|
||
else
|
||
{
|
||
var trade = DbContext.trade.Where(x => x.ValidState == "Valid" && (x.TradeStatus == ConsTrade.审批中 || x.TradeStatus == ConsTrade.平仓待复核 || x.TradeStatus == ConsTrade.行权待复核 || x.TradeStatus == ConsTrade.互换待复核)).ToList();
|
||
if (trade != null && trade.Count > 0)
|
||
{
|
||
throw new ServiceException("有交易在审批中,不能删除审批流程!");
|
||
}
|
||
}
|
||
}
|
||
else if (type == ProcessCategoryConst.Close) // 需求②:了结/平仓/行权审批流程
|
||
{
|
||
if (data != null && data.Count > 0)
|
||
{
|
||
ChangeTradeProcess(data, delList);
|
||
}
|
||
else
|
||
{
|
||
var trade = DbContext.trade.Where(x => x.ValidState == "Valid" && (x.TradeStatus == ConsTrade.平仓待复核 || x.TradeStatus == ConsTrade.行权待复核 || x.TradeStatus == ConsTrade.互换待复核)).ToList();
|
||
if (trade != null && trade.Count > 0)
|
||
{
|
||
throw new ServiceException("有交易在审批中,不能删除审批流程!");
|
||
}
|
||
}
|
||
}
|
||
else if (type == "CreditProcess")
|
||
{
|
||
if (data != null && data.Count == 0)
|
||
{
|
||
var credit = DbContext.credit.Where(x => x.ProcessOrderId > 1).ToList();
|
||
credit.ForEach(x => x.ProcessOrderId = 1);
|
||
var clientdb = DbContextFactory.GetClientDbContext(OptUser);
|
||
var clientrating = clientdb.Client_Rating.Where(x => !x.IsDeleted && x.ProcessOrderId > 1).ToList();
|
||
clientrating.ForEach(x => x.ProcessOrderId = 1);
|
||
clientdb.SaveChanges();
|
||
}
|
||
else
|
||
{
|
||
var credit = DbContext.credit.Where(x => x.ProcessStatus == "审批中").ToList();
|
||
if (credit != null && credit.Count > 0)
|
||
{
|
||
throw new ServiceException("有授信在审批中,不能删除审批流程!");
|
||
}
|
||
|
||
var clientrating = DbContextFactory.GetClientDbContext(OptUser).Client_Rating.Where(x => !x.IsDeleted && x.ProcessStatus == "审批中").ToList();
|
||
if (clientrating != null && clientrating.Count > 0)
|
||
{
|
||
throw new ServiceException("有资信评级在审批中,不能删除审批流程!");
|
||
}
|
||
}
|
||
}
|
||
else if (type == "OutCashProcess")
|
||
{
|
||
var clientCashs = DbContext.ClientCashInCashOut.Where(x => x.State == "审批中").ToList();
|
||
if (clientCashs != null && clientCashs.Count > 0)
|
||
{
|
||
if (data == null || data.Count == 0)
|
||
{
|
||
throw new ServiceException("有资金在审批中,不能删除审批流程!");
|
||
}
|
||
else
|
||
{
|
||
throw new ServiceException("有资金在审批中,不能修改审批流程!");
|
||
}
|
||
}
|
||
}
|
||
else if (type == "ClientProcess")
|
||
{
|
||
List<string> optTypes = new List<string>() { "提交信息变更审批" };
|
||
var clients = GetClients(optTypes);
|
||
if (data == null || data.Count == 0)
|
||
{
|
||
if (clients != null && clients.Count > 0)
|
||
{
|
||
throw new ServiceException("有用户在审批中,不能删除审批流程!");
|
||
}
|
||
}
|
||
else
|
||
{
|
||
ChangeClientProcess(data, clients, delList);
|
||
}
|
||
}
|
||
return DbContext.SaveChanges();
|
||
}
|
||
#region 交易审批流程 私有方法
|
||
/// <summary>
|
||
/// 交易审批流程
|
||
/// </summary>
|
||
/// <param name="data">待保存数据</param>
|
||
/// <param name="delList">旧数据</param>
|
||
/// <param name="branchNode">分支节点</param>
|
||
/// <param name="processOrderId">节点</param>
|
||
/// <exception cref="ServiceException"></exception>
|
||
/// <exception cref="Exception"></exception>
|
||
private void ChangeTradeProcess(List<ApprovalProcessAddRequest> data, approvalprocess[] delList)
|
||
{
|
||
var trades = DbContext.trade.Where(x => x.ValidState == "Valid" && (x.TradeStatus == ConsTrade.审批中 || x.TradeStatus == ConsTrade.平仓待复核 || x.TradeStatus == ConsTrade.行权待复核 || x.TradeStatus == ConsTrade.互换待复核)).ToList();
|
||
var noGroupData = data.Where(x => x.approvalGroupId == 0);
|
||
var branch = data.Where(x => x.approvalGroupId != 0);//修改有分支
|
||
var groupId = UserBLL.GetApprovalProcessGroup(UserInfo.UserId);
|
||
var oldBranch = delList.Where(x => x.approvalGroupId != 0);//旧流程有分支
|
||
bool NotChange = false;//不允许修改
|
||
if (oldBranch.Count() == 0 && branch.Count() > 0)//旧流程无分支,新流程有分支
|
||
{
|
||
NotChange = true;
|
||
}
|
||
if (oldBranch.Count() > 0 && branch.Count() == 0)//旧流程有分支,新流程无分支
|
||
{
|
||
NotChange = true;
|
||
}
|
||
if (NotChange)
|
||
{
|
||
if (trades != null && trades.Count > 0)
|
||
{
|
||
throw new ServiceException("有交易在审批中,不能修改审批流程!");
|
||
}
|
||
}
|
||
|
||
if (branch.Count() > 0)//有分支情况
|
||
{
|
||
if (groupId == 0)
|
||
{
|
||
throw new Exception("该申请人不符合任何条件分支");
|
||
}
|
||
TradeProcessHasChange(data, delList, trades, groupId);
|
||
|
||
}
|
||
else //无分支情况直接修改
|
||
{
|
||
UpdateTradeAudit(ProcessTradeLog.审批中, 0);
|
||
}
|
||
}
|
||
/// <summary>
|
||
/// 回到审批初始节点
|
||
/// </summary>
|
||
/// <param name="processOrderId"></param>
|
||
/// <param name="branchNode"></param>
|
||
private void UpdateTradeAudit(int processOrderId, int oldBranchNode, bool all = false)
|
||
{
|
||
Expression<Func<trade, bool>> expression = x => x.ProcessOrderId >= ProcessTradeLog.审批中;
|
||
if (!all)
|
||
{
|
||
expression = expression.And(x => x.ProcessOrderBranch == oldBranchNode);
|
||
}
|
||
var trades = DbContext.trade.Where(expression).ToList();
|
||
trades.ForEach(x =>
|
||
{
|
||
x.ProcessOrderId = processOrderId;
|
||
x.CheckStatus = 0;
|
||
});
|
||
}
|
||
/// <summary>
|
||
/// 有分支情况有修改
|
||
/// </summary>
|
||
/// <param name="data">新数据</param>
|
||
/// <param name="delList">旧数据</param>
|
||
/// <param name="trades">交易数据</param>
|
||
/// <returns></returns>
|
||
private void TradeProcessHasChange(List<ApprovalProcessAddRequest> data, approvalprocess[] delList, List<trade> trades, int groupId)
|
||
{
|
||
|
||
var processOrderId = data.Min(s => s.Index);
|
||
var branchData = data.Where(x => x.approvalGroupId != 0);//修改有分支
|
||
var approvalConditionFirst = branchData.FirstOrDefault(x => x.approvalGroupId == groupId && x.approvalCondition == 1);//属于某个审批组
|
||
var approvalConditionSecend = branchData.FirstOrDefault(x => x.approvalGroupId != groupId && x.approvalCondition == 2);//不属于某个审批组
|
||
var approvalProcess = approvalConditionFirst == null ? approvalConditionSecend : approvalConditionFirst;
|
||
if (approvalProcess == null)
|
||
{
|
||
throw new Exception("该申请人不符合任何条件分支");
|
||
}
|
||
var branchNode = approvalProcess.node;
|
||
var branch = branchData.First();//分支节点所在位置
|
||
var dataIds = data.Where(x => x.id != 0).Select(s => s.id).ToList();
|
||
var changeNodeIndexs = ProcessChangeIndex(data, delList);
|
||
bool NotChange = false;//不允许修改
|
||
var firstBranchTrades = trades.Where(x => x.ProcessOrderBranch == 1).ToList();
|
||
var secondBranchTrades = trades.Where(x => x.ProcessOrderBranch == 2).ToList();
|
||
if (branch.Index == processOrderId)//跳过审批组流程
|
||
{
|
||
processOrderId = processOrderId + 1;
|
||
}
|
||
//判断数据是否有变更
|
||
if (changeNodeIndexs.Count > 0)
|
||
{
|
||
var firstChange = changeNodeIndexs.Any(x => x.node == 1);//分支1有修改
|
||
var secondChange = changeNodeIndexs.Any(x => x.node == 2);//分支2有修改
|
||
var main = data.Any(x => x.node == 0);//新流程有主干
|
||
var mainChange = changeNodeIndexs.Any(x => x.node == 0);//有主节点修改-包括新增&删除
|
||
if (main || mainChange)
|
||
{
|
||
if (firstChange || secondChange)// 分支不可修改
|
||
{
|
||
if (trades.Count > 0)//有交易审批,不允许修改
|
||
{
|
||
NotChange = true;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if (mainChange && trades.Count > 0) //主节点修改回到初始
|
||
{
|
||
UpdateTradeAudit(processOrderId, 0, true);
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if (firstChange && secondChange)//分支1,2有修改
|
||
{
|
||
if (trades.Count > 0)//有交易审批,不允许修改
|
||
{
|
||
NotChange = true;
|
||
}
|
||
}
|
||
else if (firstChange && !secondChange)//只修改了分支1
|
||
{
|
||
if (firstBranchTrades.Count > 0)
|
||
{
|
||
NotChange = true;
|
||
}
|
||
|
||
}
|
||
else if (!firstChange && secondChange)//只修改了分支2
|
||
{
|
||
if (secondBranchTrades.Count > 0)
|
||
{
|
||
NotChange = true;
|
||
}
|
||
}
|
||
}
|
||
if (NotChange)
|
||
{
|
||
throw new ServiceException("有交易在审批中,不能修改审批流程!");
|
||
}
|
||
}
|
||
|
||
|
||
}
|
||
/// <summary>
|
||
/// 获取数据修改节点集合
|
||
/// </summary>
|
||
/// <param name="data">新数据</param>
|
||
/// <param name="oldList">旧数据</param>
|
||
/// <returns></returns>
|
||
private List<ApprovalProcessNode> ProcessChangeIndex(List<ApprovalProcessAddRequest> data, approvalprocess[] oldList)
|
||
{
|
||
List<ApprovalProcessNode> indexList = new List<ApprovalProcessNode>();
|
||
foreach (var item in oldList)//筛选删除的节点
|
||
{
|
||
ApprovalProcessNode upNode = new ApprovalProcessNode();
|
||
var addNode = data.FirstOrDefault(x => x.id == item.id);
|
||
if (addNode == null)
|
||
{
|
||
upNode.node = item.node ?? 0;
|
||
upNode.Index = item.order;
|
||
indexList.Add(upNode);
|
||
}
|
||
}
|
||
foreach (ApprovalProcessAddRequest item in data)//筛选新增及修改节点
|
||
{
|
||
ApprovalProcessNode upNode = new ApprovalProcessNode();
|
||
if (item.id == 0)
|
||
{
|
||
upNode.node = item.node;
|
||
upNode.Index = item.Index;
|
||
indexList.Add(upNode);
|
||
}
|
||
var oldData = oldList.FirstOrDefault(x => x.id == item.id);
|
||
if (oldData != null)
|
||
{
|
||
if (item.approvalGroupId != oldData.approvalGroupId
|
||
|| item.approvalCondition != oldData.approvalCondition
|
||
|| item.ApprovalRules != oldData.ruleType
|
||
|| item.SelectValue != oldData.roleId)
|
||
{
|
||
upNode.node = item.node;
|
||
upNode.Index = item.Index;
|
||
indexList.Add(upNode);
|
||
}
|
||
}
|
||
}
|
||
return indexList;
|
||
}
|
||
|
||
#endregion
|
||
#region 客户开户&客户信息
|
||
/// <summary>
|
||
/// 开户审批流程
|
||
/// </summary>
|
||
/// <param name="data">待保存数据</param>
|
||
/// <param name="delList">旧数据</param>
|
||
/// <param name="branchNode">分支节点</param>
|
||
/// <param name="processOrderId">节点</param>
|
||
/// <exception cref="ServiceException"></exception>
|
||
/// <exception cref="Exception"></exception>
|
||
private void ChangeClientProcess(List<ApprovalProcessAddRequest> data, List<Client> clients, approvalprocess[] delList)
|
||
{
|
||
var noGroupData = data.Where(x => x.approvalGroupId == 0);
|
||
var branch = data.Where(x => x.approvalGroupId != 0);//修改有分支
|
||
var groupId = UserBLL.GetApprovalProcessGroup(UserInfo.UserId);
|
||
var oldBranch = delList.Where(x => x.approvalGroupId != 0);//旧流程有分支
|
||
bool NotChange = false;//不允许修改
|
||
if (oldBranch.Count() == 0 && branch.Count() > 0)//旧流程无分支,新流程有分支
|
||
{
|
||
NotChange = true;
|
||
}
|
||
if (oldBranch.Count() > 0 && branch.Count() == 0)//旧流程有分支,新流程无分支
|
||
{
|
||
NotChange = true;
|
||
}
|
||
if (NotChange)
|
||
{
|
||
if (clients != null && clients.Count > 0)
|
||
{
|
||
throw new ServiceException("有用户在审批中,不能更改审批流程!");
|
||
}
|
||
}
|
||
|
||
if (branch.Count() > 0)//有分支情况
|
||
{
|
||
if (groupId == 0)
|
||
{
|
||
throw new Exception("该申请人不符合任何条件分支");
|
||
}
|
||
ClientProcessHasChange(data, delList, clients, groupId);
|
||
}
|
||
else //无分支情况直接修改
|
||
{
|
||
UpdateClientAudit(ProcessTradeLog.审批中, 0, clients);
|
||
}
|
||
}
|
||
/// <summary>
|
||
/// 回到审批初始节点
|
||
/// </summary>
|
||
/// <param name="processOrderId"></param>
|
||
/// <param name="branchNode"></param>
|
||
private void UpdateClientAudit(int processOrderId, int oldBranchNode, List<Client> clients, bool all = false)
|
||
{
|
||
var clientdb = DbContextFactory.GetClientDbContext(OptUser);
|
||
if (!all)
|
||
{
|
||
clients = clients.Where(x => x.ProcessOrderBranch == oldBranchNode).ToList();
|
||
}
|
||
var cids = clients.Select(x => x.id).ToList();
|
||
var range = clientdb.client_file_audit.Where(x => cids.Contains(x.ClientId)).ToList();
|
||
clientdb.client_file_audit.RemoveRange(range);
|
||
for (int i = 0; i < clients.Count; i++)
|
||
{
|
||
Client c = clientdb.client.Find(clients[i].id);
|
||
c.ApprovalOrderId = processOrderId;
|
||
}
|
||
clientdb.SaveChanges();
|
||
}
|
||
private List<Client> GetClients(List<string> optTypes)
|
||
{
|
||
var clientQuery = DataCacheProvider.GetClientDataSource().AsQueryable().Where(x => x.ApprovalOrderId >= ProcessTradeLog.审批中).ToList();
|
||
var clientdb = DbContextFactory.GetClientDbContext(OptUser);
|
||
var clientQuerys = from c in clientQuery
|
||
join audit in clientdb.ClientAuditLog.Where(x => optTypes.Contains(x.OptType)) on c.ApprovalLogId equals audit.id
|
||
select c;
|
||
var clients = clientQuerys.ToList();
|
||
return clients;
|
||
}
|
||
#endregion
|
||
/// <summary>
|
||
/// 有分支情况有修改
|
||
/// </summary>
|
||
/// <param name="data">新数据</param>
|
||
/// <param name="delList">旧数据</param>
|
||
/// <param name="trades">交易数据</param>
|
||
/// <returns></returns>
|
||
private void ClientProcessHasChange(List<ApprovalProcessAddRequest> data, approvalprocess[] delList, List<Client> clients, int groupId)
|
||
{
|
||
var processOrderId = data.Min(s => s.Index);
|
||
var branchData = data.Where(x => x.approvalGroupId != 0);//修改有分支
|
||
var approvalConditionFirst = branchData.FirstOrDefault(x => x.approvalGroupId == groupId && x.approvalCondition == 1);//属于某个审批组
|
||
var approvalConditionSecend = branchData.FirstOrDefault(x => x.approvalGroupId != groupId && x.approvalCondition == 2);//不属于某个审批组
|
||
var approvalProcess = approvalConditionFirst == null ? approvalConditionSecend : approvalConditionFirst;
|
||
if (approvalProcess == null)
|
||
{
|
||
throw new Exception("该申请人不符合任何条件分支");
|
||
}
|
||
var branchNode = approvalProcess.node;
|
||
var branch = branchData.First();//分支节点所在位置
|
||
var dataIds = data.Where(x => x.id != 0).Select(s => s.id).ToList();
|
||
var changeNodeIndexs = ProcessChangeIndex(data, delList);
|
||
bool NotChange = false;//不允许修改
|
||
var firstBranchClients = clients.Where(x => x.ProcessOrderBranch == 1).ToList();
|
||
var secondBranchClients = clients.Where(x => x.ProcessOrderBranch == 2).ToList();
|
||
if (branch.Index == processOrderId)//跳过审批组流程
|
||
{
|
||
processOrderId = processOrderId + 1;
|
||
}
|
||
//判断数据是否有变更
|
||
if (changeNodeIndexs.Count > 0)
|
||
{
|
||
var firstChange = changeNodeIndexs.Any(x => x.node == 1);//分支1有修改
|
||
var secondChange = changeNodeIndexs.Any(x => x.node == 2);//分支2有修改
|
||
var main = data.Any(x => x.node == 0);//新流程有主干
|
||
var mainChange = changeNodeIndexs.Any(x => x.node == 0);//有主节点修改-包括新增&删除
|
||
if (main || mainChange)
|
||
{
|
||
if (firstChange|| secondChange)// 分支不可修改
|
||
{
|
||
if (clients.Count > 0)//有交易审批,不允许修改
|
||
{
|
||
NotChange = true;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if (mainChange&& clients.Count > 0) //主节点修改回到初始
|
||
{
|
||
UpdateClientAudit(processOrderId, 0, clients, true);
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if (firstChange && secondChange)//分支1,2有修改
|
||
{
|
||
if (clients.Count > 0)//有交易审批,不允许修改
|
||
{
|
||
NotChange = true;
|
||
}
|
||
}
|
||
else if (firstChange && !secondChange)//只修改了分支1
|
||
{
|
||
if (firstBranchClients.Count > 0)
|
||
{
|
||
NotChange = true;
|
||
}
|
||
|
||
}
|
||
else if (!firstChange && secondChange)//只修改了分支2
|
||
{
|
||
if (secondBranchClients.Count > 0)
|
||
{
|
||
NotChange = true;
|
||
}
|
||
}
|
||
}
|
||
if (NotChange)
|
||
{
|
||
throw new ServiceException("有用户在审批中,不能修改审批流程!");
|
||
}
|
||
}
|
||
|
||
|
||
}
|
||
/// <summary>
|
||
/// 投资规模审核
|
||
/// </summary>
|
||
public bool CheckTradeScale(trade trade)
|
||
{
|
||
var orderId = trade.ProcessOrderId;
|
||
var um = DataCacheModule.DataCacheManager.GetUnderlyingDataSource().GetData(trade.UnderlyingId);
|
||
if (um == null)
|
||
{
|
||
return true;
|
||
}
|
||
//2021/06/23 规模审批使用deltaCash
|
||
var UsedScale = 0.0;
|
||
// 如果是审批组
|
||
var tradeProcess = TradeProcess();
|
||
var orderIdCount = tradeProcess.Where(x => x.order == trade.ProcessOrderId);//判断是否有分支
|
||
int orderNode = orderIdCount.Count() > 1 ? trade.ProcessOrderBranch : 0;
|
||
if (orderIdCount.Count() == 1)
|
||
{
|
||
orderNode = orderIdCount.First().node ?? 0;
|
||
}
|
||
var roleId = tradeProcess.OrderBy(o => o.order).FirstOrDefault(o => o.order == orderId && o.node == orderNode && o.processType == "TradeProcess").roleId;
|
||
var approvalGrade = DbContext.approvalGrade.FirstOrDefault(o => o.RoleId == roleId && o.AssetId == trade.AssetId && o.Rule == RuleEnum.投资规模);
|
||
List<trade> trades;
|
||
var underlyingPrice = DataCacheProvider.GetUnderlyingDataSource();
|
||
|
||
trades = (from t in DbContext.trade
|
||
join u in DbContext.underlying_manager
|
||
on t.UnderlyingId equals u.id
|
||
where t.AssetId == trade.AssetId
|
||
&& t.TradeType != "结构化交易"
|
||
&& ConsTrade.PositionTradeStatusList.Contains(t.TradeStatus)
|
||
&& !ConsTrade.TradeTypesForHedge.Contains(t.TradeType)
|
||
&& t.ValidState != "InValid"
|
||
select t).ToList();
|
||
trades.Add(trade);
|
||
BLL.tradeBLL.SetFieldsByTradeType(trade);
|
||
if (trades != null && trades.Count > 0)
|
||
{
|
||
var riskList = RealtimePnlCalc.RealTimeRiskCalc(SystemValueDate, trades, underlyingPrice, new List<string> { "持仓" }, false, QdpModule.QdpPricingRequest.BASIC_PRICING);
|
||
UsedScale += riskList.Sum(o => (o.DeltaCash ?? 0));
|
||
}
|
||
if (approvalGrade != null)
|
||
{
|
||
return UsedScale <= (approvalGrade.DeltaCashScale ?? 0);
|
||
}
|
||
|
||
return false;
|
||
}
|
||
|
||
public bool CheckTradeScale(int enid)
|
||
{
|
||
var trade = DbContext.trade.FirstOrDefault(o => o.id == enid);
|
||
if (trade != null)
|
||
{
|
||
return CheckTradeScale(trade);
|
||
}
|
||
else
|
||
{
|
||
throw new ServiceException("未找到交易");
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 仅审批投资规模的步骤
|
||
/// </summary>
|
||
/// <param name="trade"></param>
|
||
/// <returns>-2:该步骤存在字段审核没审核或者没有规模审核 -1:规模审核未过 0:审核直接通过 1:规模审核通过,之后的流程中存在字段审核</returns>
|
||
public int CheckTradeApprovalStep(trade trade, int userId, bool hadCheckParam = false)
|
||
{
|
||
var roles = UserBLL.GetRolesByUserId(userId).Select(o => o.Id);
|
||
var groupId = UserBLL.GetApprovalProcessGroup(userId);
|
||
// 需求②:按交易状态推断开仓/了结流程。
|
||
var tradeProcess = TradeProcessByCategory(trade);
|
||
bool approvalBranch = tradeProcess.Any(x => x.approvalGroupId != 0);//审批流程有分支情况
|
||
trade.ProcessOrderBranch = 0;
|
||
if (trade.ProcessOrderId <= 0)
|
||
{
|
||
if (approvalBranch)//审批流程有分支情况
|
||
{
|
||
//该审批组属于流程的审批组或该审批组不属于流程审批组
|
||
var tradeProessBranchQuery = tradeProcess.FirstOrDefault(x => (x.approvalGroupId == groupId && x.approvalCondition == 1) || (x.approvalGroupId != groupId && x.approvalCondition == 2));
|
||
if (tradeProessBranchQuery == null)//都没有情况
|
||
{
|
||
return -3;
|
||
}
|
||
trade.ProcessOrderId = ProcessTradeLog.审批中;
|
||
|
||
if (trade.ProcessOrderId >= tradeProessBranchQuery.order)
|
||
{
|
||
trade.ProcessOrderId = tradeProessBranchQuery.order + 1;//跳过审批组那一级
|
||
}
|
||
trade.ProcessOrderBranch = tradeProessBranchQuery.node ?? 1;//审批组分子
|
||
if (!tradeProcess.Any(x => x.order >= trade.ProcessOrderId && (x.node == trade.ProcessOrderBranch || x.node == 0)))//分支无需审批,直接通过
|
||
{
|
||
trade.ProcessOrderId = ProcessTradeLog.审批通过;
|
||
trade.CheckTradeUpdate = Convert.ToInt32(TradeCheckEnum.StatusOfNew);
|
||
trade.ProcessOptDate = DateTime.Now;
|
||
trade.ProcessStatus = ProcessTradeStatus.通过审批.ToString();
|
||
return 0;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
trade.ProcessOrderId = ProcessTradeLog.审批中;
|
||
}
|
||
}
|
||
// 需求①:开仓交易首次进入审批时,应用触发条件——跳过起始就不满足触发条件的节点。
|
||
// 若所有节点均不满足 → 直接审批通过,无需审核。
|
||
if (tradeProcess.Count > 0)
|
||
{
|
||
ApplyTriggerOnStart(tradeProcess, trade, userId);
|
||
if (trade.ProcessOrderId == ProcessTradeLog.审批通过)
|
||
{
|
||
return 0;
|
||
}
|
||
}
|
||
// 如果是审批组
|
||
var orderIdCount = tradeProcess.Where(x => x.order == trade.ProcessOrderId);//判断是否有分支
|
||
int processOrderNode = orderIdCount.Count() > 1 ? trade.ProcessOrderBranch : 0;
|
||
if (orderIdCount.Count() == 1)
|
||
{
|
||
processOrderNode = orderIdCount.First().node ?? 0;
|
||
}
|
||
var NowProcess = tradeProcess.FirstOrDefault(o => o.order == trade.ProcessOrderId && o.node == processOrderNode && roles.Contains(o.roleId));
|
||
|
||
trade.TradeStatus = ConsTrade.审批中;
|
||
trade.ProcessStatus = ProcessTradeStatus.审批中.ToString();
|
||
trade.ProcessOptDate = DateTime.Now;
|
||
|
||
if (NowProcess != null && NowProcess.ruleType != null && (NowProcess.ruleType == "1" || (NowProcess.ruleType.Contains("1") && hadCheckParam)))
|
||
{
|
||
if (CheckTradeScale(trade))
|
||
{
|
||
var process = tradeProcess.FirstOrDefault(o => o.ruleType != null && o.ruleType.Contains("0") && o.order > NowProcess.order && o.node == processOrderNode);
|
||
if (process != null)
|
||
{
|
||
trade.ProcessOrderId = process.order;
|
||
return 1;
|
||
}
|
||
else
|
||
{
|
||
trade.ProcessOrderId = ProcessTradeLog.审批通过;
|
||
trade.CheckTradeUpdate = Convert.ToInt32(TradeCheckEnum.StatusOfNew);
|
||
trade.ProcessOptDate = DateTime.Now;
|
||
trade.ProcessStatus = ProcessTradeStatus.通过审批.ToString();
|
||
return 0;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
var lastScaleProcessOrder = tradeProcess.Where(o => o.ruleType.Contains("1")).Select(o => o.order).Max();
|
||
if (trade.ProcessOrderId >= lastScaleProcessOrder)
|
||
{
|
||
throw new ServiceException($"该交易'{trade.TradeNumber}'规模审批流程最后一步的审批角色对审批簿记的投资规模依然不足!");
|
||
}
|
||
trade.ProcessOrderId = trade.ProcessOrderId + 1;
|
||
}
|
||
return -1;
|
||
}
|
||
return -2;
|
||
|
||
}
|
||
|
||
/// <summary>
|
||
/// 需求①:开仓交易首次进入审批流程时,从起始节点应用触发条件。
|
||
/// <para>跳过起始就不满足触发条件的节点;若所有节点均不满足 → 直接审批通过。</para>
|
||
/// </summary>
|
||
private void ApplyTriggerOnStart(List<approvalprocess> tradeProcess, trade trade, int userId)
|
||
{
|
||
// 取当前起点节点(主干 node=0)
|
||
var start = tradeProcess.FirstOrDefault(x => x.order == trade.ProcessOrderId && x.node == 0);
|
||
if (start == null)
|
||
{
|
||
start = tradeProcess.FirstOrDefault(x => x.order >= trade.ProcessOrderId && x.node == 0);
|
||
}
|
||
if (start == null) return;
|
||
|
||
// 构建求值上下文(开仓场景无 trade_cash,CurrentNotional 不设)
|
||
var ctx = new ConditionContext
|
||
{
|
||
UserId = userId,
|
||
Trade = trade,
|
||
ProcessCategory = ProcessCategoryConst.Resolve(trade),
|
||
InitGroupId = UserBLL.GetApprovalProcessGroup(userId)
|
||
};
|
||
|
||
var target = ConditionEvaluator.FindFirstTriggeredNode(tradeProcess, start, ctx);
|
||
|
||
if (target == null)
|
||
{
|
||
// 所有节点都不满足触发条件 → 直接审批通过
|
||
trade.ProcessOrderId = ProcessTradeLog.审批通过;
|
||
trade.CheckTradeUpdate = Convert.ToInt32(TradeCheckEnum.StatusOfNew);
|
||
trade.ProcessOptDate = DateTime.Now;
|
||
trade.ProcessStatus = ProcessTradeStatus.通过审批.ToString();
|
||
return;
|
||
}
|
||
if (target.order != trade.ProcessOrderId)
|
||
{
|
||
trade.ProcessOrderId = target.order;
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取所有交易审批节点
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
public List<approvalprocess> TradeProcess()
|
||
{
|
||
var tradeOrders = DbContext.approvalprocess.Where(t => t.processType == "TradeProcess").OrderBy(o => o.order).ToList();
|
||
return tradeOrders;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 按交易推断流程类别(开仓/了结)获取审批节点(需求②)。
|
||
/// <para>了结类优先取 CloseProcess;未配置则回退 TradeProcess。</para>
|
||
/// </summary>
|
||
public List<approvalprocess> TradeProcessByCategory(trade td)
|
||
{
|
||
var category = ProcessCategoryConst.Resolve(td);
|
||
var orders = DbContext.approvalprocess.Where(t => t.processType == category).OrderBy(o => o.order).ToList();
|
||
if (category == ProcessCategoryConst.Close && orders.Count == 0)
|
||
{
|
||
return TradeProcess();
|
||
}
|
||
return orders;
|
||
}
|
||
|
||
}
|
||
|
||
/// <summary>
|
||
/// 添加审批流程请求
|
||
/// </summary>
|
||
public class ApprovalProcessAddRequest
|
||
{
|
||
public int id { get; set; }
|
||
public string Type { get; set; }
|
||
public int Index { get; set; }
|
||
public int SelectValue { get; set; }
|
||
public string ApprovalRules { get; set; }
|
||
|
||
public int approvalGroupId { get; set; }
|
||
|
||
public int node { get; set; }
|
||
public int parentNode { get; set; }
|
||
public int approvalCondition { get; set; }
|
||
|
||
/// <summary>分支网关条件(JSON),需求①③共用。为空则回退旧 approvalGroupId/approvalCondition 二元判断。</summary>
|
||
public string conditionConfig { get; set; }
|
||
|
||
/// <summary>节点触发条件(JSON),需求①:满足才进入该审批节点,不满足则跳过。</summary>
|
||
public string triggerCondition { get; set; }
|
||
}
|
||
/// <summary>
|
||
/// 审批流程修改节点
|
||
/// </summary>
|
||
public class ApprovalProcessNode
|
||
{
|
||
public int Index { get; set; }
|
||
public int node { get; set; }
|
||
}
|
||
}
|