package company_apply import ( "encoding/json" "errors" "fmt" "hongze/hz_crm_api/models/company" "hongze/hz_crm_api/models/contract" "hongze/hz_crm_api/models/system" "hongze/hz_crm_api/services" "hongze/hz_crm_api/services/alarm_msg" cygxService "hongze/hz_crm_api/services/cygx" "hongze/hz_crm_api/services/flow" "hongze/hz_crm_api/utils" "strings" "time" ) var sourceType = 1 //来源客户 // 提交审批 func Apply(companyApprovalId int, messageContent string) (err error) { //获取客户单详情 recodeInfo, err := company.GetCompanyApprovalByApprovalId(companyApprovalId) if err != nil { err = errors.New("获取合同信息失败,Err:" + err.Error()) return } if recodeInfo == nil { err = errors.New("客户单异常,找不到客户单信息") return } //获取客户信息 companyInfo, err := company.GetCompanyById(recodeInfo.CompanyId) if err != nil { err = errors.New("获取合同信息失败,Err:" + err.Error()) return } if companyInfo == nil { err = errors.New("客户信息异常,找不到客户信息") return } //合同状态判断 ignoreStatus := []string{"待审批", "已撤回", "驳回"} if !strings.Contains(strings.Join(ignoreStatus, ","), recodeInfo.ApproveStatus) { err = errors.New("客户单状态异常,不允许提交审批,当前客户单状态:" + recodeInfo.ApproveStatus) return } //待审内容 applyContent := `试用转正式` switch recodeInfo.ApplyMethod { //"1:试用->正式,2:冻结—>试用,3:试用延期,4:原销售申请领取流失客户,5:正式客户申请服务更新" case 1: applyContent = `试用转正式` case 2: applyContent = `冻结转试用` case 3: applyContent = `试用延期` case 4: applyContent = `原销售申领客户` case 5: applyContent = `续约申请` case 6: applyContent = `补充协议` } contractDetailByte, err := json.Marshal(recodeInfo) if err != nil { err = errors.New(fmt.Sprint("合同状态异常,当前合同数据格式化失败:", err)) return } //获取基础审批流 var flowItemInfo *system.ApprovalFlowItem if recodeInfo.ProductId == 1 { tmpFlowItemInfo, tmpErr := flow.GetApprovalFlow(1) if tmpErr != nil { err = errors.New(fmt.Sprint("查找审批流程配置失败:", tmpErr)) return } flowItemInfo = tmpFlowItemInfo } else { tmpFlowItemInfo, tmpErr := flow.GetApprovalFlow(2) if tmpErr != nil { err = errors.New(fmt.Sprint("查找审批流程配置失败:", tmpErr)) return } flowItemInfo = tmpFlowItemInfo } //校验是否存在待审批的审批单(其实没有多大意义,只是为了 异常数据校验) contractApproval := &contract.ContractApproval{ ContractId: recodeInfo.CompanyApprovalId, Status: "待审批", ApprovalType: "company", ApplyContent: applyContent, ContractDetail: string(contractDetailByte), ApplyUserId: recodeInfo.ApplyUserId, ApplyUserName: recodeInfo.ApplyRealName, FlowId: flowItemInfo.FlowId, FlowVersion: flowItemInfo.CurrVersion, CurrNodeId: flowItemInfo.NodeList[0].NodeId, StartNodeId: flowItemInfo.NodeList[0].NodeId, ModifyTime: time.Now(), CreateTime: time.Now(), } has, err := contractApproval.CheckPendingByContractId(recodeInfo.CompanyApprovalId, "company") if err != nil { return } if has { err = errors.New("客户单异常,不允许提交审批,存在待审核的客户单") return } contractApprovalRecordList := make([]*contract.ContractApprovalRecord, 0) ApproveUserMap := make(map[int]system.User) for _, nodeItem := range flowItemInfo.NodeList { //审批流记录 if len(nodeItem.UserList) <= 0 { err = errors.New(fmt.Sprint("审批流程异常,没有可审批的人员,Err:", err)) return } for _, userItem := range nodeItem.UserList { contractApprovalRecord := &contract.ContractApprovalRecord{ Status: "待审批", ApproveRemark: "", ApproveUserId: userItem.AdminId, ApproveUserName: userItem.Name, ApproveRoleTypeCode: userItem.RoleTypeCode, NodeId: nodeItem.NodeId, NodeType: nodeItem.NodeType, NextNodeId: nodeItem.NextNodeId, PrevNodeId: nodeItem.PrevNodeId, AuditType: nodeItem.AuditType, CreateTime: time.Now(), ModifyTime: time.Now(), } contractApprovalRecordList = append(contractApprovalRecordList, contractApprovalRecord) ApproveUserMap[userItem.AdminId] = userItem } } err = contractApproval.Apply2(contractApproval, contractApprovalRecordList) if err != nil { return } //待办通知 { //发送消息下级审批人 go messageToNodeUser(contractApproval.CurrNodeId, recodeInfo.ApplyUserId, companyInfo.CompanyId, contractApproval.ContractId, contractApproval.ContractApprovalId, 1, 1, companyInfo.CompanyName, messageContent) } return } // CancelApply 撤回审批 func CancelApply(recordInfo *company.CompanyApproval, opUserId int) (err error) { if recordInfo == nil { err = errors.New("客户单异常,没有客户单信息") return } //客户单状态判断 if recordInfo.ApproveStatus != "待审批" { err = errors.New("客户单状态异常,不允许撤回申请,当前客户单状态:" + recordInfo.ApproveStatus) return } //校验操作人与客户单申请人是否同一人 if recordInfo.ApplyUserId != opUserId { err = errors.New(fmt.Sprint("操作人异常,不允许撤回非本人提交的申请;客户单发起人:", recordInfo.ApplyUserId, ";撤销人:", opUserId)) return } //获取最近一次待审批的审批单信息 approval, err := contract.GetLastPendingContractApprovalByContractId(recordInfo.CompanyApprovalId, "company") if err != nil { return } //是否一级审批节点判断,如果不是一级审批节点,那么不允许撤回 if approval.StartNodeId != approval.CurrNodeId { err = errors.New("审批单状态异常,不允许撤回申请,当前审批单已被审批操作,进入了下一级审批节点") return } //获取当前待审批的审批流信息 approvalRecord, err := contract.GetCurrContractApprovalRecordByContractId(approval.ContractApprovalId) if err != nil { return } //判断当前节点是否存在上级节点,如果存在,那么说明 if approvalRecord.PrevNodeId > 0 { err = errors.New("合同已存在审批操作,不允许撤回申请") return } //获取当前审批单中所有待审批的流程流 approvalRecordList, err := contract.GetPendingContractApprovalRecordListByContractId(approval.ContractApprovalId, approvalRecord.NodeId) if err != nil { return } //撤回审批流 err = approval.Cancel(approval, approvalRecordList) if err != nil { return } //添加操作日志 (??这个看情况再说,或许没有必要) //作废原有消息 //for _, contractApprovalRecord := range approvalRecordList { // go company.CancelCompanyApprovalMessage(contractApprovalRecord.ContractApprovalRecordId, 2) //} go company.CancelCompanyApprovalMessage(approval.ContractId, 2) return } // Reject 驳回审批 func Reject(approvalRecord *contract.ContractApprovalRecord, opUser *system.Admin, rejectRemark string) (err error) { if approvalRecord == nil { err = errors.New("审批流异常,没有审批流信息") return } //审批流状态判断 if approvalRecord.Status != "待审批" { err = errors.New("审批流状态异常,不允许驳回申请,当前审批流状态:" + approvalRecord.Status) return } //判断是否审批类型,如果不是审批类型,那么就没有审批权限 if approvalRecord.NodeType != "check" { err = errors.New("当前账号没有审批权限") return } //操作人 opUserId := opUser.AdminId opUserName := opUser.RealName //操作权限校验 //if opUser.RoleTypeCode != approvalRecord.ApproveRoleTypeCode { // err = errors.New("当前账号没有审批权限") // return //} if approvalRecord.ApproveUserId > 0 && approvalRecord.ApproveUserId != opUserId { err = errors.New("当前账号没有审批权限,需要指定人操作") return } //获取审批单详情 approval, err := contract.GetContractApprovalById(approvalRecord.ContractApprovalId) if err != nil { return } //审批单状态判断 if approval.Status != "待审批" { err = errors.New("审批单状态异常,不允许驳回申请,当前审批单状态:" + approval.Status) return } //获取 客户单 信息 recordInfo, err := company.GetCompanyApprovalByCompanyApprovalId(approval.ContractId) if err != nil { return } //客户单 状态判断 if recordInfo.ApproveStatus != "待审批" { err = errors.New("客户单状态异常,不允许驳回申请,当前客户单状态:" + recordInfo.ApproveStatus) return } //获取 客户 信息 companyInfo, err := company.GetCompanyById(recordInfo.CompanyId) if err != nil { return } err = approval.Reject(approval, approvalRecord, opUserId, opUserName, rejectRemark) if err != nil { return } //添加操作日志 //remark := "驳回申请" //_ = contract.AddContractOperationRecord(contractInfo.ContractId, opUserId, approvalRecord.ContractApprovalRecordId, "reject", opUserName, remark) //完成审批后的驳回操作 go afterReject(approval.ContractId, opUserId, opUserName, rejectRemark) //待办通知 { //content := contractInfo.CompanyName + " 合同模板已驳回" content := companyInfo.CompanyName + " " + recordInfo.ApproveContent + "审批驳回" approvalSysUser, _ := system.GetSysAdminById(approval.ApplyUserId) go services.AddCompanyApprovalMessage(opUserId, approval.ApplyUserId, companyInfo.CompanyId, approval.ContractId, 2, sourceType, 3, companyInfo.CompanyName, content, content, approvalSysUser.Mobile) } return } // Approved 审批通过 func Approved(approvalRecord *contract.ContractApprovalRecord, opUser *system.Admin, approvedRemark string) (err error) { if approvalRecord == nil { err = errors.New("审批流异常,没有审批流信息") return } //审批流状态判断 if approvalRecord.Status != "待审批" { err = errors.New("审批流状态异常,不允许审批,当前审批流状态:" + approvalRecord.Status) return } //判断是否审批类型,如果不是审批类型,那么就没有审批权限 if approvalRecord.NodeType != "check" { err = errors.New("当前账号没有审批权限") return } //操作人 opUserId := opUser.AdminId //opUserName := opUser.RealName //操作权限校验 //if opUser.RoleTypeCode != approvalRecord.ApproveRoleTypeCode { // err = errors.New("当前账号没有审批权限") // return //} if approvalRecord.ApproveUserId > 0 && approvalRecord.ApproveUserId != opUserId { err = errors.New("当前账号没有审批权限,需要指定人操作") return } //获取审批单详情 approval, err := contract.GetContractApprovalById(approvalRecord.ContractApprovalId) if err != nil { return } //审批单状态判断 if approval.Status != "待审批" { err = errors.New("审批单状态异常,不允许审批,当前审批单状态:" + approval.Status) return } //获取 客户单 信息 recordInfo, err := company.GetCompanyApprovalByCompanyApprovalId(approval.ContractId) if err != nil { return } //客户单 状态判断 if recordInfo.ApproveStatus != "待审批" { err = errors.New("客户单状态异常,不允许审批,当前客户单状态:" + recordInfo.ApproveStatus) return } //获取 客户 信息 companyInfo, err := company.GetCompanyById(recordInfo.CompanyId) if err != nil { return } err = approval.Approved(approval, approvalRecord, approvedRemark) if err != nil { return } //添加操作日志 //remark := "审批通过" //_ = contract.AddContractOperationRecord(contractInfo.ContractId, opUserId, approvalRecord.ContractApprovalRecordId, "approval", opUserName, remark) //发送信息给所有抄送人 content := companyInfo.CompanyName + " " + recordInfo.ApproveContent + "审批通过" //如果下一个节点属于结束节点,那么通知对应的销售,同时,异步生成合同pdf if approvalRecord.NextNodeId == 0 { //待办通知(通知销售已经审核通过了) { approvalSysUser, _ := system.GetSysAdminById(approval.ApplyUserId) go services.AddCompanyApprovalMessage(opUserId, approval.ApplyUserId, companyInfo.CompanyId, approval.ContractId, 2, sourceType, 2, companyInfo.CompanyName, content, content, approvalSysUser.Mobile) } // 客户单审批后的异步操作(修改客户单信息、修改合同权限等) go func() { _ = afterApproved(recordInfo.CompanyApprovalId, opUser.AdminId, opUser.RealName) // 注意此处下面的处理原本都是各开了协程,现改为只在一个协程里处理,不然可能会导致数据还没完全更新,紧接着就被错误更新对应的数据 if recordInfo.ProductId == 2 && recordInfo.CompanyContractId > 0 { // 处理权益客户的身份信息() cygxService.UpdateCygxCompanyUserType(recordInfo.CompanyContractId) //if recordInfo.ApplyMethod == 1 { //获取合同信息 contractInfo, tmpErr := company.GetCompanyContractDetail(recordInfo.CompanyId, recordInfo.ProductId, recordInfo.CompanyContractId) if tmpErr != nil { err = errors.New(fmt.Sprint("待审批信息不存在,CompanyId:", recordInfo.CompanyId, ";productId:", recordInfo.ProductId, ";Err:"+tmpErr.Error())) return } if contractInfo == nil { err = errors.New(fmt.Sprint("待审批信息不存在,CompanyId:", recordInfo.CompanyId, ";productId:", recordInfo.ProductId)) return } //格式化合同开始时间 contractStartDate, tmpErr := time.Parse(utils.FormatDate, contractInfo.StartDate) if tmpErr != nil { err = errors.New("合同开始时间转换失败,Err:" + tmpErr.Error()) return } if time.Now().After(contractStartDate) { cygxService.ActivitySpecialCompanyApproval(recordInfo.CompanyId, recordInfo.CompanyContractId, companyInfo.CompanyName) //审批通过的时候专项调研次数更新 //cygxService.ActivitySpecialCompanyApproval(recordInfo.CompanyContractId) //审批通过的时候专项调研次数更新 } //} //权益销售客户申请转正后,消息群发给所有销售 services.AddCompanyApprovalMessageRai(recordInfo.CompanyId, recordInfo.CompanyContractId, recordInfo.ApplyRealName, companyInfo.CompanyName) //客户研选行业转正时(王芳审批通过),模板消息提醒汪洋 services.AddCompanyApprovalMessageWangYang(recordInfo.CompanyId, recordInfo.CompanyContractId, recordInfo.ApplyRealName, companyInfo.CompanyName) cygxService.YanXuanCompanyApproval(recordInfo.CompanyId, recordInfo.CompanyContractId) //研选审批通过的时候研选扣点更新 cygxService.HandleCompanyContractTypeByRaiXClass(recordInfo.CompanyContractId) //所有x类试用转正的合同都记为 :打分派点 //cygxService.HandleAllocationCompanyContractByYanXuan(recordInfo.CompanyContractId) //如果合同只有研选的时候,自动处理派点 cygxService.HandleCompanyContractPackageDifference(recordInfo.CompanyContractId) // 更新与上一份合同的金额的对比 '增加套餐','减少套餐','维持套餐' cygxService.HandleCompanyContractPermissionContractType(recordInfo.CompanyContractId) // 更新合同权限表中的权限名称,以及对应的行业权限类型(行业新签、行业续约) services.UpdateCompanyProductSellerMove(recordInfo.CompanyId, recordInfo.ProductId) // 权益客户创建新的有效合同之后,更新所关联的销售信息 } }() } else { //获取下级节点信息 flowNodeInfo, tmpErr := system.GetByNodeId(approvalRecord.NextNodeId) if tmpErr != nil { err = tmpErr return } //如果该级节点是抄送类型,那么需要将该节点给处理掉 if flowNodeInfo.NodeType == "cc" { go approvedByCc(approvedRemark, approvalRecord) } else { //发送消息下级审批人 go messageToNodeUser(approvalRecord.NextNodeId, approval.ApplyUserId, companyInfo.CompanyId, approval.ContractId, approval.ContractApprovalId, 1, 1, companyInfo.CompanyName, content) } } return } // approvedByCc 审批通过(抄送节点) func approvedByCc(approvedRemark string, sourceApprovalRecord *contract.ContractApprovalRecord) (err error) { //下个流程节点id nextNodeId := 0 //获取审批单中抄送节点的所有数据列表 approvalRecordList, err := contract.GetContractApprovalRecordListByContractIdAndNode(sourceApprovalRecord.ContractApprovalId, sourceApprovalRecord.NextNodeId) if err != nil { return } //遍历所有的抄送单 for _, contractApprovalRecord := range approvalRecordList { nextNodeId = contractApprovalRecord.NextNodeId //审批流状态判断 if contractApprovalRecord.Status != "待审批" { err = errors.New("审批流状态异常,不允许审批,当前审批流状态:" + contractApprovalRecord.Status) return } //判断是否审批类型,如果不是审批类型,那么就没有审批权限 if contractApprovalRecord.NodeType != "cc" { err = errors.New("当前账号不是抄送权限") return } } //获取审批单详情 approval, err := contract.GetContractApprovalById(sourceApprovalRecord.ContractApprovalId) if err != nil { return } //获取 客户单 信息 recordInfo, err := company.GetCompanyApprovalByCompanyApprovalId(approval.ContractId) if err != nil { return } //客户单 状态判断 if recordInfo.ApproveStatus != "待审批" { err = errors.New("客户单状态异常,不允许审批,当前客户单状态:" + recordInfo.ApproveStatus) return } //获取 客户 信息 companyInfo, err := company.GetCompanyById(recordInfo.CompanyId) if err != nil { return } //if contractApprovalRecord err = approval.ApprovedByCc(approval, approvalRecordList, approvedRemark, nextNodeId) if err != nil { return } content := companyInfo.CompanyName + " " + recordInfo.ApproveContent + "审批通过" //发送消息给抄送人 go messageToNodeUser(approvalRecordList[0].NodeId, approval.ApplyUserId, companyInfo.CompanyId, approval.ContractId, approval.ContractApprovalId, 1, 1, companyInfo.CompanyName, content) //如果下一个节点属于结束节点,那么通知对应的销售,同时,异步生成合同pdf if nextNodeId == 0 { //待办通知 { approvalSysUser, _ := system.GetSysAdminById(approval.ApplyUserId) go services.AddCompanyApprovalMessage(sourceApprovalRecord.ApproveUserId, approval.ApplyUserId, companyInfo.CompanyId, approval.ContractId, 2, sourceType, 2, companyInfo.CompanyName, content, content, approvalSysUser.Mobile) } //客户单审批后的异步操作(修改客户单信息、修改合同权限等) go afterApproved(recordInfo.CompanyApprovalId, sourceApprovalRecord.ApproveUserId, sourceApprovalRecord.ApproveUserName) } else { //获取下级节点信息 flowNodeInfo, tmpErr := system.GetByNodeId(nextNodeId) if tmpErr != nil { err = tmpErr return } //如果下级节点是抄送类型,那么还是需要处理抄送节点逻辑 if flowNodeInfo.NodeType == "cc" { go approvedByCc(approvedRemark, sourceApprovalRecord) } else { //如果下级级节点是审批类型 //发送消息下级审批人 go messageToNodeUser(nextNodeId, approval.ApplyUserId, companyInfo.CompanyId, approval.ContractId, approval.ContractApprovalId, 1, 1, companyInfo.CompanyName, content) } } return } // messageToNodeUser 抄送信息给用户(根据节点来推送) func messageToNodeUser(flowNodeId, createUserId, companyId, companyApprovalId, contractApprovalId, messageType, approvalStatus int, companyName, content string) (err error) { //获取审批单中抄送节点的所有数据列表 contractApprovalRecordList, err := contract.GetContractApprovalRecordListByContractIdAndNode(contractApprovalId, flowNodeId) if err != nil { return } err = messageToUser(contractApprovalRecordList, createUserId, companyId, companyApprovalId, messageType, approvalStatus, companyName, content) return } // messageToAllCcUser 发送信息给所有抄送人 // @param createUserId 消息发起人 // @param contractApprovalId 审批单id // @param messageType 消息类型:1:申请消息,2:审批结果 // @param approvalStatus 审批状态:1:待审批,2:已审批,3:已驳回" // @param companyName 企业客户名称 // @param content 消息内容 func messageToAllCcUser(createUserId, companyId, companyApprovalId, contractApprovalId, messageType, approvalStatus int, companyName, content string) (err error) { //获取审批单中抄送节点的所有数据列表 contractApprovalRecordList, err := contract.GetContractApprovalRecordListByContractApprovalId(contractApprovalId) if err != nil { return } err = messageToUser(contractApprovalRecordList, createUserId, companyId, companyApprovalId, messageType, approvalStatus, companyName, content) return } // messageToUser 抄送信息给用户(发送给所有抄送人) // @param createUserId 待审批、抄送记录 // @param createUserId 消息发起人 // @param contractApprovalId 审批单id // @param messageType 消息类型:1:申请消息,2:审批结果 // @param approvalStatus 审批状态:1:待审批,2:已审批,3:已驳回" // @param companyName 企业客户名称 // @param content 消息内容 func messageToUser(contractApprovalRecordList []*contract.ContractApprovalRecord, createUserId, companyId, companyApprovalId, messageType, approvalStatus int, companyName, content string) (err error) { for _, contractApprovalRecord := range contractApprovalRecordList { sysUserMobile := "" sysUser, _ := system.GetSysAdminById(contractApprovalRecord.ApproveUserId) if sysUser != nil { sysUserMobile = sysUser.Mobile } //接收人,就是审批记录里面的待审核人(抄送人) receiveUserId := contractApprovalRecord.ApproveUserId go services.AddCompanyApprovalMessage(createUserId, receiveUserId, companyId, companyApprovalId, messageType, sourceType, approvalStatus, companyName, content, content, sysUserMobile) } return } // afterApproved 审批完成后操作 func afterApproved(companyApprovalId int, opUserId int, opUserName string) (err error) { defer func() { if err != nil { //fmt.Println("异常提醒:"+utils.RunMode, "合同审批通过后,生成pdf失败,ERR:"+err.Error()+"", utils.EmailSendToUsers) go alarm_msg.SendAlarmMsg("客户审批通过后,处理客户失败,Err:"+err.Error(), 3) //go utils.SendEmail("异常提醒:"+utils.RunMode, "客户审批通过后,处理客户失败,ERR:"+err.Error()+"", utils.EmailSendToUsers) } }() opUser := system.Admin{ AdminId: opUserId, RealName: opUserName, } //获取客户单详情 recodeInfo, err := company.GetCompanyApprovalByApprovalId(companyApprovalId) if err != nil { err = errors.New("获取合同信息失败,Err:" + err.Error()) return } if recodeInfo == nil { err = errors.New("客户单异常,找不到客户单信息") return } //获取客户信息 companyInfo, err := company.GetCompanyById(recodeInfo.CompanyId) if err != nil { err = errors.New("获取合同信息失败,Err:" + err.Error()) return } if companyInfo == nil { err = errors.New("客户信息异常,找不到客户信息") return } //客户产品信息 companyProduct, err := company.GetCompanyProductByCompanyIdAndProductId(recodeInfo.CompanyId, recodeInfo.ProductId) if err != nil { err = errors.New(fmt.Sprint("获取信息客户产品失败", ";Err:"+err.Error())) return } if companyProduct == nil { err = errors.New("获取信息客户产品失败2") return } //recodeInfo. logSellerId := recodeInfo.ApplyUserId logSellerName := recodeInfo.ApplyRealName isAddCompanyProductUpdateLog := true //是否添加变更日志 companyReportPermissionList := make([]*company.CompanyReportPermission, 0) //需要变更的品种列表 var startDate, endDate string //变更到最新的日期 switch recodeInfo.ApplyMethod { case 1: //试用转正式 //获取合同信息 contractInfo, tmpErr := company.GetCompanyContractDetail(recodeInfo.CompanyId, recodeInfo.ProductId, recodeInfo.CompanyContractId) if tmpErr != nil { err = errors.New(fmt.Sprint("待审批信息不存在,CompanyId:", recodeInfo.CompanyId, ";productId:", recodeInfo.ProductId, ";Err:"+tmpErr.Error())) return } if contractInfo == nil { err = errors.New(fmt.Sprint("待审批信息不存在,CompanyId:", recodeInfo.CompanyId, ";productId:", recodeInfo.ProductId)) return } //格式化合同开始时间 contractStartDate, tmpErr := time.Parse(utils.FormatDate, contractInfo.StartDate) if tmpErr != nil { err = errors.New("合同开始时间转换失败,Err:" + tmpErr.Error()) return } //格式化合同结束日期 contractEndDate, tmpErr := time.Parse(utils.FormatDate, contractInfo.EndDate) if tmpErr != nil { err = errors.New("合同结束时间转换失败,Err:" + tmpErr.Error()) return } //格式化 产品中 合同结束日期 //productContractEndDate, err := time.Parse(utils.FormatDate, companyProduct.ContractEndDate) //if err != nil { // br.Msg = "审批失败" // br.ErrMsg = "产品中合同结束时间转换失败,Err:" + err.Error() // return //} //如果是权益的用户客户转正审批单独走 if companyProduct.Status == utils.COMPANY_STATUS_FOREVER && companyProduct.ProductId == 2 { //contractInfo.StartDate = contractStartDate.AddDate(0, 4, 0).Format(utils.FormatDate) // 开始时间与结束时间都加三个月 //contractInfo.EndDate = contractEndDate.AddDate(0, 4, 0).Format(utils.FormatDate) startDate = contractInfo.StartDate endDate = contractInfo.EndDate companyReportPermissionList, tmpErr = company.TryOutToFormalXClassRai(recodeInfo.CompanyId, recodeInfo.ProductId, opUser.AdminId, recodeInfo.CompanyApprovalId, contractInfo.CompanyContractId, contractInfo.StartDate, contractInfo.EndDate, opUser.RealName, companyProduct.ProductName, contractInfo.RaiPackageType) if tmpErr != nil { err = errors.New("试用转正式失败,Err:" + tmpErr.Error()) return } } else { //如果合同时间小于等于今天,那么立马执行合同内容 if time.Now().After(contractStartDate) { startDate = contractInfo.StartDate endDate = contractInfo.EndDate companyReportPermissionList, tmpErr = company.TryOutToFormal(recodeInfo.CompanyId, recodeInfo.ProductId, opUser.AdminId, recodeInfo.CompanyApprovalId, contractInfo.CompanyContractId, contractInfo.StartDate, contractInfo.EndDate, opUser.RealName, companyProduct.ProductName, contractInfo.PackageType, contractInfo.RaiPackageType) if tmpErr != nil { err = errors.New("试用转正式失败,Err:" + tmpErr.Error()) return } } else { tmpErr = company.ApplyApproveContract(recodeInfo.CompanyId, recodeInfo.ProductId, recodeInfo.CompanyApprovalId, contractInfo.CompanyContractId) if tmpErr != nil { err = errors.New("试用转正式失败,Err:" + tmpErr.Error()) return } //不添加日志 isAddCompanyProductUpdateLog = false } //如果合同中的结束日期大于产品中的合同结束日期,那么就去修改产品中的合同结束日期 if contractEndDate.After(companyProduct.ContractEndDate) { companyProduct.ContractEndDate = contractEndDate cols := make([]string, 0) cols = append(cols, "ContractEndDate") _ = companyProduct.Update(cols) } } case 2: //冻结->试用 //权益的 x类试用转冻结的申请解冻 if companyProduct.InitStatus == utils.COMPANY_STATUS_FOREVER && companyProduct.ProductId == utils.COMPANY_PRODUCT_RAI_ID { tmpCompanyReportPermissionList, tmpStartDate, tmpEndDate, tmpErr := company.FreezeToTryOutXClassRai(recodeInfo.CompanyId, recodeInfo.ProductId, opUser.AdminId, recodeInfo.CompanyApprovalId, recodeInfo.ApplyUserId, opUser.RealName, companyProduct.ProductName) if tmpErr != nil { err = errors.New("冻结转试用失败,Err:" + tmpErr.Error()) return } companyReportPermissionList = tmpCompanyReportPermissionList startDate = tmpStartDate endDate = tmpEndDate } else { tmpCompanyReportPermissionList, tmpStartDate, tmpEndDate, tmpErr := company.FreezeToTryOut(recodeInfo.CompanyId, recodeInfo.ProductId, opUser.AdminId, recodeInfo.CompanyApprovalId, recodeInfo.ApplyUserId, opUser.RealName, companyProduct.ProductName) if tmpErr != nil { err = errors.New("冻结转试用失败,Err:" + tmpErr.Error()) return } companyReportPermissionList = tmpCompanyReportPermissionList startDate = tmpStartDate endDate = tmpEndDate } case 3: //试用延期 tmpCompanyReportPermissionList, tmpEndDate, tmpErr := company.TryOutDelay(recodeInfo.CompanyId, recodeInfo.ProductId, opUser.AdminId, recodeInfo.CompanyApprovalId, opUser.RealName, companyProduct.EndDate, companyProduct.ProductName) if tmpErr != nil { err = errors.New("试用延期失败,Err:" + tmpErr.Error()) return } companyReportPermissionList = tmpCompanyReportPermissionList startDate = companyProduct.StartDate endDate = tmpEndDate case 4: //原销售申请领取流失客户 sellerItem, tmpErr := system.GetSysAdminById(recodeInfo.ApplyUserId) if tmpErr != nil { err = errors.New("找不到申请的销售,Err:" + tmpErr.Error()) return } companyReportPermissionList, startDate, endDate, tmpErr = company.ApplyReceive(recodeInfo.CompanyId, recodeInfo.ProductId, opUser.AdminId, recodeInfo.CompanyApprovalId, sellerItem, opUser.RealName, companyProduct.ProductName, sellerItem.RealName, sellerItem.AdminId) if tmpErr != nil { err = errors.New("原销售申请领取流失客户失败,Err:" + tmpErr.Error()) return } logSellerId = sellerItem.AdminId logSellerName = sellerItem.RealName case 5, 6: //正式客户申请服务更新 //获取合同信息 contractInfo, tmpErr := company.GetCompanyContractDetail(recodeInfo.CompanyId, recodeInfo.ProductId, recodeInfo.CompanyContractId) if tmpErr != nil { err = errors.New(fmt.Sprint("正式客户申请服务更新失败,待审批合同信息不存在,CompanyId:", recodeInfo.CompanyId, ";productId:", recodeInfo.ProductId, ";Err:"+tmpErr.Error())) return } if contractInfo == nil { err = errors.New(fmt.Sprint("正式客户申请服务更新失败,待审批合同信息不存在2,CompanyId:", recodeInfo.CompanyId, ";productId:", recodeInfo.ProductId)) return } //格式化合同开始时间 contractStartDate, tmpErr := time.Parse(utils.FormatDate, contractInfo.StartDate) if tmpErr != nil { err = errors.New(fmt.Sprint("正式客户申请服务更新失败,合同开始时间转换失败;Err:" + tmpErr.Error())) return } //格式化合同结束日期 contractEndDate, tmpErr := time.Parse(utils.FormatDate, contractInfo.EndDate) if tmpErr != nil { err = errors.New(fmt.Sprint("正式客户申请服务更新失败,合同结束时间转换失败;Err:" + tmpErr.Error())) return } //格式化 产品中 合同结束日期 //productContractEndDate, err := time.Parse(utils.FormatDate, companyProduct.ContractEndDate) //if err != nil { // br.Msg = "审批失败" // br.ErrMsg = "产品中合同结束时间转换失败,Err:" + err.Error() // return //} //如果合同时间小于等于今天,那么立马执行合同内容 if time.Now().After(contractStartDate) { // 合同处理完成后的续约异常记录 contactHandleCompanyRenewalRecord(contractInfo) startDate = contractInfo.StartDate endDate = contractInfo.EndDate companyReportPermissionList, err = company.ApplyServiceUpdate(recodeInfo.CompanyId, recodeInfo.ProductId, opUser.AdminId, recodeInfo.CompanyApprovalId, recodeInfo.CompanyContractId, companyProduct.StartDate, contractInfo.EndDate, opUser.RealName, companyProduct.ProductName, contractInfo.PackageType, contractInfo.RaiPackageType) if err != nil { err = errors.New(fmt.Sprint("正式客户申请服务更新失败,执行失败;Err:" + err.Error())) return } } else { tmpErr = company.ApplyApproveContract(recodeInfo.CompanyId, recodeInfo.ProductId, recodeInfo.CompanyApprovalId, recodeInfo.CompanyContractId) if tmpErr != nil { err = errors.New(fmt.Sprint("正式客户申请服务更新失败,执行失败2;Err:" + tmpErr.Error())) return } //不添加日志 isAddCompanyProductUpdateLog = false } //如果合同中的结束日期大于产品中的合同结束日期,那么就去修改产品中的合同结束日期 if contractEndDate.After(companyProduct.ContractEndDate) { companyProduct.ContractEndDate = contractEndDate cols := make([]string, 0) cols = append(cols, "ContractEndDate") _ = companyProduct.Update(cols) } default: err = errors.New(fmt.Sprint("无效的审批状态,CompanyId:", recodeInfo.CompanyId, ";productId:", recodeInfo.ProductId, ";ApplyMethod:", recodeInfo.ApplyMethod, ";ApproveStatus:", recodeInfo.ApproveStatus)) return } //新增客户产品日志 { productLog := new(company.CompanyProductLog) productLog.CompanyProductId = companyProduct.CompanyProductId productLog.CompanyId = companyProduct.CompanyId productLog.ProductId = companyProduct.ProductId productLog.ProductName = companyProduct.ProductName productLog.CompanyName = companyProduct.CompanyName productLog.CompanyName = companyProduct.CompanyName productLog.Source = companyProduct.Source productLog.Reasons = companyProduct.Reasons productLog.Status = companyProduct.Status productLog.IndustryId = companyProduct.IndustryId productLog.IndustryName = companyProduct.IndustryName productLog.SellerId = companyProduct.SellerId productLog.SellerName = companyProduct.SellerName productLog.GroupId = companyProduct.GroupId productLog.DepartmentId = companyProduct.DepartmentId productLog.IsSuspend = companyProduct.IsSuspend productLog.SuspendTime = companyProduct.SuspendTime productLog.ApproveStatus = companyProduct.ApproveStatus productLog.FreezeTime = companyProduct.FreezeTime productLog.Remark = companyProduct.Remark productLog.StartDate = companyProduct.StartDate productLog.EndDate = companyProduct.EndDate productLog.CreateTime = companyProduct.CreateTime productLog.ModifyTime = companyProduct.ModifyTime productLog.LoseReason = companyProduct.LoseReason productLog.LossTime = companyProduct.LossTime productLog.LogType = "modify" productLog.LogCreateTime = time.Now() productLog.AdminId = opUserId go company.AddCompanyProductLog(productLog) } //新增操作记录 { remark := "审批" operation := "approve" approveContent := "审批通过" if companyProduct.Status == utils.COMPANY_STATUS_FOREVER && companyProduct.InitStatus == utils.COMPANY_STATUS_FOREVER && companyProduct.ProductId == 2 { //权益永续客户申请内容做变更 //123月份申请转正通过时,将试用期限延长(更新)至4.30。456月份申请转正通过时,将试用期限延长至7.31。789月份申请转正通过时,将试用期限延长至10.31。101112月份申请转正通过时,将试用期限延长至次年1.31。 endDateContent := utils.GetLastDayOfQuarter(time.Now()).Format(utils.FormatDate) approveContent += ",试用延期至" + endDateContent } services.AddCompanyOperationRecord(recodeInfo.CompanyId, companyProduct.SellerId, opUserId, recodeInfo.ProductId, opUserId, companyProduct.CompanyName, companyProduct.ProductName, opUserName, remark, operation, approveContent, opUserName, "", companyProduct.Status) } //新增客户产品状态变更日志 if isAddCompanyProductUpdateLog { updateSource := `` switch recodeInfo.ApplyMethod { case 1: //试用转正式 updateSource = `turn_positive` case 2: //冻结->试用 updateSource = "thaw" case 3: //试用延期 updateSource = "delay" case 4: //原销售申请领取流失客户 updateSource = "apply_receive" case 5: //正式客户申请续约 updateSource = "service_update" case 6: //正式客户新增补充协议 updateSource = "add_agreement" } startDateTime, _ := time.ParseInLocation(utils.FormatDate, startDate, time.Local) endDateTime, _ := time.ParseInLocation(utils.FormatDate, endDate, time.Local) companyProductUpdateLog := &company.CompanyProductUpdateLog{ Id: 0, CompanyId: companyProduct.CompanyId, ProductId: companyProduct.ProductId, Status: companyProduct.Status, SellerId: logSellerId, SellerName: logSellerName, Source: updateSource, StartDate: startDateTime, EndDate: endDateTime, RealEndDate: startDateTime, IsFormal: companyProduct.IsFormal, //是否已经转正式,0是没有转正式,1是已经转过正式 CreateTime: time.Now(), } go company.AddCompanyProductUpdateLog(companyProductUpdateLog) // 2: //冻结->试用;3: //试用延期;4: //原销售申请领取流失客户; if recodeInfo.ApplyMethod == 2 || recodeInfo.ApplyMethod == 3 || recodeInfo.ApplyMethod == 4 { companyProductTryOutUpdateLog := &company.CompanyProductTryOutUpdateLog{ Id: 0, CompanyId: companyProduct.CompanyId, ProductId: companyProduct.ProductId, SellerId: logSellerId, SellerName: logSellerName, Source: updateSource, StartDate: startDateTime, EndDate: endDateTime, RealEndDate: startDateTime, IsStop: 0, CreateTime: time.Now(), } go company.AddCompanyProductTryOutUpdateLog(companyProductTryOutUpdateLog, companyReportPermissionList) } } return } // contactHandleCompanyRenewalRecord // @Description: 合同处理完成后的续约异常记录 // @author: Roc // @datetime 2023-12-07 14:24:44 // @param contractInfo *company_contract.CompanyContract // @param day string // @return err error func contactHandleCompanyRenewalRecord(contractInfo *company.CompanyContractDetail) { var err error defer func() { if err != nil { utils.FileLog.Error("合同处理完成后的续约异常记录," + err.Error()) } }() // 判断合同类型是否是续约合同,如果不是的话,就不往下走了 if contractInfo.ContractType != `续约合同` { return } day := time.Now().Format(utils.FormatDate) // 获取早于当前合同结束日期的上一份合同 lastContract, tmpErr := company.GetLastContractListByEndDate(contractInfo.CompanyId, contractInfo.ProductId, contractInfo.EndDate) if tmpErr != nil { err = errors.New(fmt.Sprint("合同id:", contractInfo.CompanyContractId, ";通过最近一份合同的日期获取早于该合同的最晚一份合同失败,ERR:", tmpErr)) return } // 校验 上一份合同的结束日期 与 今天 相隔的天数 betweenDay, tmpErr := utils.GetDaysBetween2Date(utils.FormatDate, day, lastContract.EndDate) if tmpErr != nil { err = errors.New(fmt.Sprint("合同id:", contractInfo.CompanyContractId, ";计算两个日期相差的天数失败,ERR:", tmpErr)) return } source := 2 // 正常续约 // 如果间隔时间超过60天,那么标记为超时续约 if betweenDay > 60 { source = 3 // 超时续约 } // 如果间隔时间超过60天,那么标记为超时续约 companyProductItem, tmpErr := company.GetCompanyProductItemByCompanyId(contractInfo.CompanyId, contractInfo.ProductId) if tmpErr != nil { err = errors.New(fmt.Sprint("合同id:", contractInfo.CompanyContractId, ";GetCompanyProductItemByCompanyId失败,ERR:", tmpErr)) return } var shareSellerId int var shareSellerName string if companyProductItem.IsShare == 1 { shareSellerId = companyProductItem.ShareSellerId shareSellerName = companyProductItem.ShareSeller } item := &company.CompanyRenewalRecord{ Id: 0, CompanyId: contractInfo.CompanyId, ProductId: contractInfo.ProductId, Source: source, SellerId: companyProductItem.SellerId, SellerName: companyProductItem.SellerName, ShareSellerId: shareSellerId, ShareSellerName: shareSellerName, CreateTime: time.Now(), ModifyTime: time.Now(), } tmpErr = item.Add() if tmpErr != nil { err = errors.New(fmt.Sprint("合同id:", contractInfo.CompanyContractId, ";添加续约异常记录失败,ERR:", tmpErr)) } return } // afterReject 驳回完成后操作 func afterReject(companyApprovalId, opUserId int, opUserName, remark string) (err error) { defer func() { if err != nil { fmt.Println("异常提醒:"+utils.RunMode, "客户审批失败后,客户操作异常,ERR:"+err.Error()+"", utils.EmailSendToUsers) go alarm_msg.SendAlarmMsg("客户审批驳回后,客户操作异常,Err:"+err.Error(), 3) //go utils.SendEmail("异常提醒:"+utils.RunMode, "合同审批失败后,合同操作异常,ERR:"+err.Error()+"", utils.EmailSendToUsers) } }() //获取客户单详情 recodeInfo, err := company.GetCompanyApprovalByApprovalId(companyApprovalId) if err != nil { err = errors.New("获取合同信息失败,Err:" + err.Error()) return } if recodeInfo == nil { err = errors.New("客户单异常,找不到客户单信息") return } //获取客户信息 companyInfo, err := company.GetCompanyById(recodeInfo.CompanyId) if err != nil { err = errors.New("获取合同信息失败,Err:" + err.Error()) return } if companyInfo == nil { err = errors.New("客户信息异常,找不到客户信息") return } //客户产品信息 companyProduct, err := company.GetCompanyProductByCompanyIdAndProductId(recodeInfo.CompanyId, recodeInfo.ProductId) if err != nil { err = errors.New(fmt.Sprint("获取信息客户产品失败", ";Err:"+err.Error())) return } if companyProduct == nil { err = errors.New("获取信息客户产品失败2") return } approveStatus := "驳回" err = company.ApproveRefuse(recodeInfo.CompanyId, recodeInfo.ProductId, approveStatus, remark) if err != nil { err = errors.New("客户单审批驳回失败,Err:" + err.Error()) return } //新增客户产品日志 { productLog := new(company.CompanyProductLog) productLog.CompanyProductId = companyProduct.CompanyProductId productLog.CompanyId = companyProduct.CompanyId productLog.ProductId = companyProduct.ProductId productLog.ProductName = companyProduct.ProductName productLog.CompanyName = companyProduct.CompanyName productLog.CompanyName = companyProduct.CompanyName productLog.Source = companyProduct.Source productLog.Reasons = companyProduct.Reasons productLog.Status = companyProduct.Status productLog.IndustryId = companyProduct.IndustryId productLog.IndustryName = companyProduct.IndustryName productLog.SellerId = companyProduct.SellerId productLog.SellerName = companyProduct.SellerName productLog.GroupId = companyProduct.GroupId productLog.DepartmentId = companyProduct.DepartmentId productLog.IsSuspend = companyProduct.IsSuspend productLog.SuspendTime = companyProduct.SuspendTime productLog.ApproveStatus = companyProduct.ApproveStatus productLog.FreezeTime = companyProduct.FreezeTime productLog.Remark = companyProduct.Remark productLog.StartDate = companyProduct.StartDate productLog.EndDate = companyProduct.EndDate productLog.CreateTime = companyProduct.CreateTime productLog.ModifyTime = companyProduct.ModifyTime productLog.LoseReason = companyProduct.LoseReason productLog.LossTime = companyProduct.LossTime productLog.LogType = "modify" productLog.LogCreateTime = time.Now() productLog.AdminId = opUserId go company.AddCompanyProductLog(productLog) } //新增操作记录 { remark := "审批" operation := "approve" approveContent := "审批驳回" services.AddCompanyOperationRecord(recodeInfo.CompanyId, companyProduct.SellerId, opUserId, recodeInfo.ProductId, opUserId, companyProduct.CompanyName, companyProduct.ProductName, opUserName, remark, operation, approveContent, opUserName, remark, companyProduct.Status) } return } // CheckApproveAuth 校验审批操作权限 func CheckApproveAuth(companyId, productId int, opUser *system.Admin) (approvalItem *company.CompanyApproval, approvalInfo *contract.ContractApproval, approvalRecord *contract.ContractApprovalRecord, err error) { //客户单详情 approvalItem, err = company.GetCompanyApprovalById(companyId, productId) if err != nil { err = errors.New("获取客户单失败,Err:" + err.Error()) return } //客户单状态判断 if approvalItem.ApproveStatus != "待审批" { err = errors.New("客户单状态异常,不允许操作申请,当前客户单状态:" + approvalItem.ApproveStatus) return } //获取该最近一条审批单详情 approvalInfo, err = contract.GetLastContractApprovalByContractId(approvalItem.CompanyApprovalId, "company") if err != nil { err = errors.New("获取审批单失败,Err:" + err.Error()) return } if approvalInfo.Status != "待审批" { err = errors.New("当前审批单状态异常,不允许审批,审批单状态:" + approvalInfo.Status) return } //审批流 approvalRecordList, err := contract.GetContractApprovalRecordListByContractApprovalIdAndNodeId(approvalInfo.ContractApprovalId, approvalInfo.CurrNodeId) if err != nil { err = errors.New("获取审批失败,Err:" + err.Error()) return } for _, tmpApprovalRecord := range approvalRecordList { if tmpApprovalRecord.NodeType == "check" && tmpApprovalRecord.ApproveUserId == opUser.AdminId { approvalRecord = tmpApprovalRecord } } if approvalRecord == nil { err = errors.New("当前账号没有审批权限") return } return }