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); } } } }