using BaseOUDAL;
using DocumentFormat.OpenXml.Spreadsheet;
using Qdp.Pricing.Library.Base.Utilities;
using YLErp.BLL;
using YLErp.CustomizedBizLogic;
using YLErp.Model.Enum;
namespace YLErp.Modules.ClientModule
{
///
/// 客户审核流程服务
///
public class ClientProcessService : ClientBaseService
{
public ClientProcessService(OptUserInfo userInfo) : base(userInfo)
{
}
public ClientProcessService(BaseService baseService) : base(baseService)
{
}
///
/// 提交审批
///
public string SubmitProcess(int clientId, out Client client)
{
try
{
client = DbContext.client.FirstOrDefault(s => s.id == clientId);
var bankcardService = new ClientBankCardService(OptUser);
if (client == null)
{
throw new ServiceException("请先保存用户基本信息");
}
CheckModel(client);
if (PS.Config.IsGuoJun && client.SupProtocolDate == null && client.ConfirmBookMode == "单章版")
{
client.SupProtocolDate = client.ProtocolSignDate;
}
//未设置流程 直接设置成开户状态
var openProcess = yldb.approvalprocess.Where(s => s.processType == "OpenProcess").ToList();
if (openProcess.Count == 0)
{
client.ProcessStatus = "已开户";
client.ProcessOrderId = -2;
client.ProcessOptDate = DateTime.Now;
if (string.IsNullOrEmpty(client.Number))
{
BizLogicSingleton.Instance.GenerateClientCode(client, DbContext.client);
}
//每一个成功开户的客户(即首次从【开户管理】转到【客户列表】),系统会自动在【资信等级】页面对该客户留下第一条“资信等级”记录,
//但是具体等级是什么,适用期限(生效日期、到期日期)是什么,都空着,待风控人员来填写;
if (!DbContext.Client_Rating.Any(x => !x.IsDeleted && x.ClientId == clientId))
{
var emptyRating = new ClientRating
{
ClientId = client.id,
ClientName = client.Name,
ClientNumber = client.Number,
Comments = "开户成功生成",
OptId = UserId,
OptName = UserName,
OptDate = DateTime.Now,
RatingStartDate = valuedateBLL.ValueDate
};
emptyRating.RatingDeadLine = emptyRating.RatingStartDate.Value.AddYears(99);
var defaultRating = DbContext.credit_rating.Where(x => x.ValidState == "Valid").FirstOrDefault();
emptyRating.CreditRatingId = defaultRating?.id ?? 0;
emptyRating.CreditRatingStr = defaultRating?.CreditName;
emptyRating.ProcessStatus = "未审批";
emptyRating.ProcessOrderId = 0;
emptyRating.ProcessOptDate = DateTime.Now;
DbContext.Client_Rating.Add(emptyRating);
yldb.SaveChanges();
}
bankcardService.SetBankCardValidStateWhenClientReEnable((int)client.id, DbContext);
DbContext.SaveChanges();
return "已开户";
}
if (client.ProcessStatus == "已开户")
{
throw new ServiceException("已开户,无需再次提交");
}
if (client.ApprovalStatus == "审批中")
{
throw new ServiceException("正在审批中");
}
var oldApprovalStatus = client.ApprovalStatus;
var groupId = UserBLL.GetApprovalProcessGroup(UserId);
bool approvalBranch = openProcess.Any(x => x.approvalGroupId != 0);//审批流程有分支情况
client.ProcessOrderBranch = 0;
client.ApprovalOrderId = ProcessTradeLog.审批中;
client.ApprovalStatus = "审批中";
client.ApprovalOptDate = DateTime.Now;
client.ProcessOrderId = -1;
client.ProcessStatus = client.ProcessStatus == "未提交" ? "未开户" : client.ProcessStatus;
client.ProcessOptDate = DateTime.Now;
if (approvalBranch)//审批流程有分支情况
{
//该审批组属于流程的审批组或该审批组不属于流程审批组
var tradeProessBranchQuery = openProcess.FirstOrDefault(x => (x.approvalGroupId == groupId && x.approvalCondition == 1) || (x.approvalGroupId != groupId && x.approvalCondition == 2));
if (tradeProessBranchQuery == null)//都没有情况
{
throw new ServiceException("当前存在分支开户审批流程,检测到申请人不满足任意一个分支进入条件,无法提交审批,请更换申请人或调整审批组");
}
client.ApprovalOrderId = tradeProessBranchQuery.order > 1 ? 1 : tradeProessBranchQuery.order + 1;//第一个节点是分支需要跳过审批组那一级
client.ProcessOrderBranch = tradeProessBranchQuery.node ?? 1;//审批组分支
}
var clientauditlog = new ClientAuditLog
{
ClientId = client.id,
OptType = oldApprovalStatus == "已拒绝" ? "重新提交开户审批" : "提交开户审批",
Changes = string.Empty,
DataType = "00",
OptId = UserId,
OptName = UserName,
OptDate = DateTime.Now
};
DbContext.ClientAuditLog.Add(clientauditlog);
DbContext.SaveChanges();
client.ApprovalLogId = clientauditlog.id;
DbContext.SaveChanges();
if (oldApprovalStatus == "已拒绝")
{
return "已重新提交审批";
}
bankcardService.SetBankCardValidStateWhenClientReEnable((int)client.id, DbContext);
DbContext.SaveChanges();
return "已提交,正在审批中";
}
catch (Exception ex)
{
LogFactory.GetLogger().Error("提交开户审批", ex);
throw new ServiceException("异常 提交开户审批失败:" + ex.Message);
}
}
private void CheckModel(Client req)
{
if (string.IsNullOrWhiteSpace(req.Name))
{
throw new ServiceException("客户名称 必须填写");
}
if (DbContext.client_black.Any(c => c.Name == req.Name && ClientBlackApprovalPolicy.EffectiveStates.Contains(c.State)))
{
throw new ServiceException("该客户为黑名单客户,无法进行下一步操作");
}
if (DbContext.client.Any(c => c.id != req.id && c.Name == req.Name && (c.ProcessStatus == "已开户" || c.ApprovalStatus == "审批中" || c.ProcessStatus == "已休眠")))
{
throw new ServiceException("客户名称不能重复");
}
//if (string.IsNullOrWhiteSpace(req.LicenseCode))
//{
// throw new ServiceException("证照编号 必须填写");
//}
//if (!string.IsNullOrWhiteSpace(req.LicenseCode) && !CheckLicenseCode(req.LicenseCode) && req.LicenseType == LicenseTypeEnum.营业执照.ToString())
//{
// throw new ServiceException("证照编号 不合法");
//}
if (DbContext.client.Any(x => x.id != req.id && x.Number == req.Number && !string.IsNullOrEmpty(req.Number)))
{
throw new ServiceException("客户编号不能重复");
}
if (!PS.Config.Is国泰君安 && PS.Config.ComponentVersion == Configuration.ComponentVersion.Broker)
{
if (DbContext.client.Any(x => x.id != req.id && x.Code == req.Code && !string.IsNullOrEmpty(req.Code)))
{
throw new ServiceException("客户代码不能重复");
}
}
if (DbContext.client.Any(x => x.id != req.id && x.DefaultLoginName == req.DefaultLoginName && !string.IsNullOrEmpty(req.DefaultLoginName)))
{
throw new ServiceException("默认登录名不能重复");
}
if (req.id == 0)
{
return;
}
if (req.ParentId > 0 && Treeleveldata(req.id).Any(c => c.id == req.ParentId))
{
throw new ServiceException("所属机构不能选择下一层");
}
//存在已审批或审批中的资质评级
if (PS.Config.ClientElement.IsCreditLimit && req.IsCreditOn != 1 && DbContext.Client_Rating.Where(t => !t.IsDeleted && t.ClientId == req.id
&& (t.ProcessStatus == "已审批" || t.ProcessStatus == "审批中")
&& (!t.RatingDeadLine.HasValue || t.RatingDeadLine >= valuedateBLL.ValueDate)).Any())
{
throw new ServiceException("存在已审批或审批中的资质评级, 请先处理相关资质评级记录");
}
//存在已审批或审批中的授信
if (PS.Config.ClientElement.IsCreditLimit && req.IsCreditOn != 1 && yldb.credit.Where(t => t.ClientId == req.id && (t.ProcessStatus == "已审批" || t.ProcessStatus == "审批中") && (!t.CreditDeadLine.HasValue || t.CreditDeadLine >= valuedateBLL.ValueDate)).Any())
{
throw new ServiceException("存在已审批或审批中的授信, 客户期权费授信不能为否,请先处理相关授信记录");
}
//产品用户投资者,如果存在收益互换权限 只有专业投资者权益百分比可以大于20%
if (req.ClientType == ClientTypeEnum.产品.ToString() && req.DerivativesInvestmentVarieties.Contains((int)DerivativesInvestmentVarietiesEnum.场外互换 + ""))
{
//获取产品投资人
var hasClientInvestors = DbContext.ClientInvestor.Where(t => t.ClientId == req.id && !"专业投资者".Equals(t.EligibilityType) && t.ShareRate > 0.2);
if (hasClientInvestors != null && hasClientInvestors.Count() > 0)
{
throw new ServiceException("本产品客户,存在非专业投资人权益比例大于20%情况,无法进行场外互换交易!");
}
}
}
private bool CheckLicenseCode(string licenseCode)
{
//原来按网上的规则实现了对15位和18位营业执照的检查,后来又客户发现了规则例外,甚至有出现17位
//的营业执照编号,因此只能先放宽要求
return licenseCode.Length >= 15 && licenseCode.Length <= 18;
}
private List Treeleveldata(int clientid)
{
var resultList = new List();
var clientQuery = DataCacheProvider.GetClientDataSource().AsQueryable();
FoundChildNode(clientQuery, clientid, resultList);
return resultList;
}
private void FoundChildNode(IQueryable clientQuery, int parentId, List resultList)
{
var childItems = clientQuery.Where(c => c.ParentId == parentId).ToList();
foreach (var child in childItems)
{
resultList.Add(child);
FoundChildNode(clientQuery, child.id, resultList);
}
}
}
}