package contract import ( "encoding/json" "errors" "fmt" "github.com/beego/beego/v2/client/orm" "hongze/hongze_mobile_admin/models/custom" contractCustom "hongze/hongze_mobile_admin/models/custom/contract" contractReq "hongze/hongze_mobile_admin/models/request/contract" contractResp "hongze/hongze_mobile_admin/models/response/contract" "hongze/hongze_mobile_admin/models/tables/chart_permission" "hongze/hongze_mobile_admin/models/tables/company_report_permission" "hongze/hongze_mobile_admin/models/tables/contract" "hongze/hongze_mobile_admin/models/tables/contract_approval" "hongze/hongze_mobile_admin/models/tables/contract_approval_record" "hongze/hongze_mobile_admin/models/tables/contract_operation_record" "hongze/hongze_mobile_admin/models/tables/contract_relation" "hongze/hongze_mobile_admin/models/tables/contract_service_detail" "hongze/hongze_mobile_admin/models/tables/contract_service_template" "hongze/hongze_mobile_admin/services" "hongze/hongze_mobile_admin/utils" "mime/multipart" "reflect" "strings" "time" ) // InvalidContract 作废合同 func InvalidContract(contractId int, opUser *custom.AdminWx) (err error) { //查询当前合同信息 nowContract, err := contract.GetContractById(contractId) if err != nil { if err.Error() == utils.ErrNoRow() { err = errors.New(fmt.Sprint("根据合同编号:", contractId, " 找不到初始合同")) } return } if nowContract.SellerId != opUser.AdminId && opUser.RoleTypeCode != utils.ROLE_TYPE_CODE_COMPLIANCE { err = errors.New("当前账号无操作权限") return } if nowContract.Status != "已审批" { err = errors.New("合同状态异常,不允许作废,当前合同状态:" + nowContract.Status) return } //如果删除状态 >0,那么代表已经被删除了 if nowContract.IsDelete > 0 { err = errors.New("该合同已删除") return } //合同作废 err = contract.InvalidContract(nowContract) if err != nil { return } //添加操作日志 remark := "作废合同模板" _ = contract_operation_record.AddContractOperationRecord(nowContract.ContractId, opUser.AdminId, 0, "invalid", opUser.RealName, remark) //修改业务合同的已支付金额 if nowContract.ContractBusinessType == "代付合同" { go updateContractPaidPriceByPaymentOnBehalfContractId(nowContract.ContractId, -nowContract.Price) } return } // GetContractDetail 根据id获取合同详情(包含服务) func GetContractDetail(contractId int) (contractDetail *contract.ContractDetail, err error) { contractDetail, err = getContractDetail(contractId) if err != nil { if err.Error() == utils.ErrNoRow() { err = errors.New("找不到该合同") } return } relationContractDetailList := make([]*contract.ContractDetail, 0) switch contractDetail.ContractBusinessType { case "业务合同": tmpList, tmpErr := contract_relation.GetContractRelationListByRelationContractId(contractDetail.ContractId) if tmpErr != nil { err = errors.New("查询业务关联合同异常:" + tmpErr.Error()) return } //获取所有关联合同详情 for _, relationContract := range tmpList { tmpContractDetail, tmpErr := getContractDetail(relationContract.PaymentOnBehalfContractId) if tmpErr != nil { err = errors.New("查询业务关联合同详情异常:" + tmpErr.Error()) return } relationContractDetailList = append(relationContractDetailList, tmpContractDetail) } case "代付合同": tmpList, tmpErr := contract_relation.GetContractRelationListByPaymentOnBehalfContractId(contractDetail.ContractId) if tmpErr != nil { err = errors.New("查询代付关联合同异常:" + tmpErr.Error()) return } //获取所有关联合同详情 for _, relationContract := range tmpList { tmpContractDetail, tmpErr := getContractDetail(relationContract.ContractId) if tmpErr != nil { err = errors.New("查询业务关联合同详情异常:" + tmpErr.Error()) return } relationContractDetailList = append(relationContractDetailList, tmpContractDetail) } } contractDetail.RelationContractDetailList = relationContractDetailList return } // getContractDetail 根据id获取合同详情(包含服务) func getContractDetail(contractId int) (contractDetail *contract.ContractDetail, err error) { contractDetail, err = contract.GetContractDetailById(contractId) if err != nil { if err.Error() == utils.ErrNoRow() { err = errors.New("找不到该合同") } return } //获取合同服务内容详情 serviceList, err := contractCustom.GetContractServiceAndDetailList(contractId) if err != nil { err = errors.New(fmt.Sprint("查找合同服务异常", err)) return } // 权益合同主客观合并 if len(serviceList) > 0 && serviceList[0].ProductId == 2 { mergeList := EquityMergeSubjectAndObject(serviceList) serviceList = mergeList } newLen := len(serviceList) for i := 0; newLen > i; i++ { if serviceList[i].HasDetail == "是" { list, detailErr := contract_service_detail.GetContractServiceDetailListByServiceId(serviceList[i].ContractServiceId) if detailErr != nil { err = errors.New(fmt.Sprint("查找合同服务详情异常", detailErr)) return } serviceList[i].DetailList = list } } contractDetail.Service = serviceList return } // UploadCheckBackFileByFile 上传签回合同附件 func UploadCheckBackFileByFile(contractId int, ext string, fileMulti multipart.File, opUser *custom.AdminWx) (resourceUrl string, err error) { //获取合同信息 contractInfo, err := contract.GetContractById(contractId) if err != nil { return } //合同状态判断 if contractInfo.Status != "已审批" && contractInfo.Status != "已签回" { err = errors.New("合同状态异常,不允许上传签回合同附件,当前合同状态:" + contractInfo.Status) return } //保存的文件名 fileName := contractInfo.CompanyName + "_" + contractInfo.ContractCode + "(签回)" //非正式环境下,文件名上面还是加上随机数 if utils.RunMode != "release" { fileName += "_" + utils.GetRandStringNoSpecialChar(10) } fileName += ext //上传到阿里云 resourceUrl, err = services.UploadToOssAndFileName(fileMulti, fileName) if err != nil { err = errors.New("文件保存失败,Err:" + err.Error()) return } contractInfo.CheckBackFileUrl = resourceUrl contractInfo.Status = "已签回" contractInfo.ModifyTime = time.Now() contractInfo.CheckBackFileTime = time.Now() err = contractInfo.Update([]string{"CheckBackFileUrl", "Status", "ModifyTime", "CheckBackFileTime"}) if err != nil { return } //同步更新客户那边提交审批的合同 o := orm.NewOrm() sql := `update company_contract set img_url = ? where contract_code=? and source="系统合同" ` _, err = o.Raw(sql, contractInfo.CheckBackFileUrl, contractInfo.ContractCode).Exec() //添加操作日志 remark := "上传签回合同附件" _ = contract_operation_record.AddContractOperationRecord(contractInfo.ContractId, opUser.AdminId, 0, "upload", opUser.RealName, remark) return } // UploadCheckBackFile 更新上传签回合同附件 func UploadCheckBackFile(contractId int, fileUrl string, opUser *custom.AdminWx) (err error) { //获取合同信息 contractInfo, err := contract.GetContractById(contractId) if err != nil { return } //合同状态判断 if contractInfo.Status != "已审批" && contractInfo.Status != "已签回" { err = errors.New("合同状态异常,不允许上传签回合同附件,当前合同状态:" + contractInfo.Status) return } contractInfo.CheckBackFileUrl = fileUrl contractInfo.Status = "已签回" contractInfo.ModifyTime = time.Now() contractInfo.CheckBackFileTime = time.Now() err = contractInfo.Update([]string{"CheckBackFileUrl", "Status", "ModifyTime", "CheckBackFileTime"}) if err != nil { return } //同步更新客户那边提交审批的合同 o := orm.NewOrm() sql := `update company_contract set img_url = ? where contract_code=? and source="系统合同" ` _, err = o.Raw(sql, contractInfo.CheckBackFileUrl, contractInfo.ContractCode).Exec() //添加操作日志 remark := "上传签回合同附件" _ = contract_operation_record.AddContractOperationRecord(contractInfo.ContractId, opUser.AdminId, 0, "upload", opUser.RealName, remark) return } // GetOpButton 获取审批流和权限 func GetOpButton(contractInfo *contract.ContractDetail, contractApprovalInfo *contract_approval.ContractApproval, opUser *custom.AdminWx) (contractOpButton contractResp.OpButton, flowNodeListResp [][]contract_approval_record.ContractApprovalRecord, err error) { //审批流 approvalRecordList, err := contract_approval_record.GetContractApprovalRecordListByContractApprovalId(contractApprovalInfo.ContractApprovalId) if err != nil { err = errors.New("获取审批失败,Err:" + err.Error()) return } flowNodeMap := make(map[int][]contract_approval_record.ContractApprovalRecord, 0) keySort := make([]int, 0) for _, approvalRecord := range approvalRecordList { //如果当前节点正好是该节点,同时审批单状态是待审批状态,然后当前账号又有权限,该账号也正是审批人,那么允许审批操作 if contractApprovalInfo.CurrNodeId == approvalRecord.NodeId && contractApprovalInfo.Status == "待审批" { if opUser.AdminId == approvalRecord.ApproveUserId && approvalRecord.NodeType == "check" { contractOpButton.Approval = true } } if tmpFlowNodeList, ok := flowNodeMap[approvalRecord.NodeId]; ok { flowNodeMap[approvalRecord.NodeId] = append(tmpFlowNodeList, *approvalRecord) } else { tmpFlowNodeList := make([]contract_approval_record.ContractApprovalRecord, 1) tmpFlowNodeList[0] = *approvalRecord flowNodeMap[approvalRecord.NodeId] = tmpFlowNodeList keySort = append(keySort, approvalRecord.NodeId) } } for _, key := range keySort { flowNodeListResp = append(flowNodeListResp, flowNodeMap[key]) } //是否具有签回合同权限 uploadStatus := []string{"已审批", "已签回"} if opUser.RoleTypeCode == utils.ROLE_TYPE_CODE_COMPLIANCE && strings.Contains(strings.Join(uploadStatus, ","), contractInfo.Status) { contractOpButton.UploadFile = true } //作废权限 if (opUser.RoleTypeCode == utils.ROLE_TYPE_CODE_COMPLIANCE || opUser.AdminId == contractInfo.SellerId) && contractInfo.Status == "已审批" { contractOpButton.Invalid = true } return } // GetContractDetailByContractId 根据合同获取合同详情 func GetContractDetailByContractId(contractId int, opUser *custom.AdminWx) (contractInfo *contract.ContractDetail, flowNodeListResp [][]contract_approval_record.ContractApprovalRecord, opButton contractResp.OpButton, err error) { contractInfo, err = GetContractDetail(contractId) if err != nil { err = errors.New("获取合同详情失败,ERR:" + err.Error()) return } contractInfo.StartDateStr = contractInfo.StartDate.Format(utils.FormatDate) contractInfo.EndDateStr = contractInfo.EndDate.Format(utils.FormatDate) contractInfo.ModifyTimeStr = contractInfo.ModifyTime.Format(utils.FormatDateTime) contractInfo.CreateTimeStr = contractInfo.CreateTime.Format(utils.FormatDateTime) //合同中包含的产品权限 isNeedPermission := false //是否需要列出来套餐中的详细权限 for _, service := range contractInfo.Service { if service.ServiceTemplateId == 2 { //小套餐才需要列出来详细的权限 isNeedPermission = true } } if isNeedPermission { permissionLookList, _ := GetPermissionByContractService(contractInfo.ProductId, contractInfo.Service) contractInfo.PermissionLookList = permissionLookList } //查询最近一次审批单信息 lastApprovalInfo, err := contract_approval.GetLastContractApprovalByContractId(contractInfo.ContractId, "contract") if err != nil { if err.Error() != utils.ErrNoRow() { err = errors.New("获取最近一次审批单信息失败,ERR:" + err.Error()) } err = nil return } if lastApprovalInfo != nil { //审批操作权限,上传签回文件权限 tmpContractOpButton, tmpFlowNodeListResp, tmpErr := GetOpButton(contractInfo, lastApprovalInfo, opUser) if tmpErr != nil { err = errors.New("获取合同按钮权限、审批流程失败,ERR:" + tmpErr.Error()) return } opButton = tmpContractOpButton flowNodeListResp = tmpFlowNodeListResp } return } // GetProductCelData 获取品种列数据(因为前端可以随意插入列数据,所以需要根据列名来搜索对应的品种列) func GetProductCelData(detail contract_service_detail.ContractServiceDetail, tableCel *contractReq.AddContractServiceDetailReq) (err error) { t := reflect.TypeOf(detail) v := reflect.ValueOf(detail) for k := 0; k < t.NumField(); k++ { //获取结构体的参数名 tmpName := t.Field(k).Name if strings.Contains(tmpName, "Col") { //获取结构体该参数名的值 tmpValue := v.Field(k).String() //如果值不为空的话,那么做下json转换 if tmpValue != "" { tmpErr := json.Unmarshal([]byte(tmpValue), tableCel) if tmpErr != nil { err = tmpErr continue } if tableCel.HeadName == "品种" { err = nil return } } } } return } // GetPermissionByContractService 通过合同服务,获取权限集合列表 func GetPermissionByContractService(productId int, serviceList []*contractCustom.ContractServiceAndDetail) (permissionList []*company_report_permission.PermissionLookList, err error) { //子权限切片集合 var permissionClassifyArr []*chart_permission.ChartPermission if productId == 1 { // 查询一级分类名称 permissionClassifyArr, err = chart_permission.GetPermissionFirstByProductId(productId) if err != nil { err = fmt.Errorf("获取权限失败,Err:%s", err.Error()) return } } else { permissionClassifyArr, err = chart_permission.GetPermissionFirstByProductId(productId) if err != nil { err = fmt.Errorf("获取权限失败,Err:%s", err.Error()) return } } //获取已经勾选的的权限 checkPermissionIdMap, err := GetServicePermissionMap(serviceList) if err != nil { return } //遍历获取 for _, v := range permissionClassifyArr { checkList := make([]int, 0) plist := new(company_report_permission.PermissionLookList) items, tmpErr := company_report_permission.GetPermissionLookByParentId(productId, v.ChartPermissionId) if tmpErr != nil { err = tmpErr return } for _, n := range items { if _, ok := checkPermissionIdMap[n.ChartPermissionId]; ok { checkList = append(checkList, n.ChartPermissionId) } } plist.Items = items plist.ClassifyName = v.PermissionName plist.CheckList = checkList permissionList = append(permissionList, plist) } return } // GetServicePermissionMap 获取合同服务中的权限id map func GetServicePermissionMap(serviceList []*contractCustom.ContractServiceAndDetail) (checkPermissionIdMap map[int]int, err error) { checkPermissionIdMap = make(map[int]int) //获取已经勾选的的权限 for _, contractService := range serviceList { //如果是权益,那么研选必要 if contractService.ProductId == 2 { chartPermissionId := 31 //研 选服务 checkPermissionIdMap[chartPermissionId] = chartPermissionId } //看看系统中有没有映射对应的权限,如果有的话,那么直接返回,没有那么可能是特殊服务,需要去遍历 if contractService.ChartPermissionId > 0 { checkPermissionIdMap[contractService.ChartPermissionId] = contractService.ChartPermissionId continue } switch contractService.ServiceTemplateId { case 1: //ficc 大套餐 // 查询一级分类名称 allFiccPermissions, e := company_report_permission.GetPermissionLookItemsByProductId(utils.COMPANY_PRODUCT_FICC_ID) if e != nil { err = fmt.Errorf("获取权限信息失败,Err:%s", e.Error()) return } permissionMap := make(map[int][]*company_report_permission.PermissionLookItem, 0) for _, v := range allFiccPermissions { if v.ParentId > 0 { permissionMap[v.ParentId] = append(permissionMap[v.ParentId], v) } } for _, v := range allFiccPermissions { if v.ParentId == 0 { if v.PermissionName == "市场策略" { continue } items, ok := permissionMap[v.ChartPermissionId] if ok { for _, n := range items { checkPermissionIdMap[n.ChartPermissionId] = n.ChartPermissionId } } } } /*for _, v := range utils.PermissionFiccClassifyArr { //大套餐中 市场策略暂时不作为勾选项 if v == "市场策略" { continue } items, tmpErr := company_report_permission.GetPermissionLookItems(1, v) if tmpErr != nil { err = tmpErr return } for _, n := range items { checkPermissionIdMap[n.ChartPermissionId] = n.ChartPermissionId } }*/ case 2: //ficc小套餐 permissionValues := []string{ "FICC周报", "商品双周报+线上电话会讨论会
(由弘则的研究员主持线上讨论)", "数据点评", } for _, detail := range contractService.DetailList { var tableCel contractReq.AddContractServiceDetailReq tmpErr := json.Unmarshal([]byte(detail.Col1), &tableCel) if tmpErr != nil { err = tmpErr return } if strings.Contains(strings.Join(permissionValues, ","), tableCel.Value) { //获取品种列数据 var tableCel2 contractReq.AddContractServiceDetailReq tmpErr := GetProductCelData(*detail, &tableCel2) if tmpErr != nil { err = tmpErr return } for _, serviceId := range tableCel2.ValueId { checkPermissionIdMap[serviceId] = serviceId } } } case 4, 5, 6: //权益大套餐 permissionFiccClassifyArr := []string{"权益"} for _, v := range permissionFiccClassifyArr { items, tmpErr := company_report_permission.GetPermissionLookItems(2, v) if tmpErr != nil { err = tmpErr return } for _, n := range items { //如果是专家行业,那么 结束当前循环,进入下一循环(产品需求:专家行业不在里面) if n.ChartPermissionId == 29 { continue } checkPermissionIdMap[n.ChartPermissionId] = n.ChartPermissionId } } } } return } // CRM8.8-权益合同主客观套餐合并 func EquityMergeSubjectAndObject(serviceList []*contractCustom.ContractServiceAndDetail) (mergeList []*contractCustom.ContractServiceAndDetail) { serviceLen := len(serviceList) if serviceLen == 0 { return serviceList } mergeArr := []string{"医药", "消费", "科技", "智造"} // 获取模板列表 templateList, e := contract_service_template.GetAllContractServiceTemplateList() if e != nil { return serviceList } parentTempMap := make(map[string]int, 0) templateMap := make(map[int]*contract_service_template.ContractServiceTemplate, 0) for _, v := range templateList { if utils.InArrayByStr(mergeArr, v.Title) { parentTempMap[v.Title] = v.ServiceTemplateId } templateMap[v.ServiceTemplateId] = v } // 计算每个行业的子套餐数, 并判断所有套餐所属行业 countIndustryMap := make(map[string]int, 0) serviceIndustryMap := make(map[int]string, 0) industryServiceMap := make(map[string]*contractCustom.ContractServiceAndDetail, 0) childrenServiceMap := make(map[string]*contractCustom.ContractServiceAndDetail, 0) for i := 0; i < serviceLen; i++ { temp := templateMap[serviceList[i].ServiceTemplateId] if temp == nil { continue } // 行业套餐 if utils.InArrayByStr(mergeArr, temp.Title) { serviceIndustryMap[serviceList[i].ContractServiceId] = temp.Title industryServiceMap[temp.Title] = serviceList[i] continue } // 主/客观 parentTemp := templateMap[temp.Pid] if parentTemp != nil && utils.InArrayByStr(mergeArr, parentTemp.Title) { countIndustryMap[parentTemp.Title] += 1 serviceIndustryMap[serviceList[i].ContractServiceId] = parentTemp.Title childrenServiceMap[parentTemp.Title] = serviceList[i] } } mergeList = make([]*contractCustom.ContractServiceAndDetail, 0) // 遍历每一个套餐, 取出所属的行业, 不属于合并的行业则直接加入数组 // 属于合并的行业, 则校验行业子套餐数, 若子套餐数为1, 则取取主/客观套餐, 否则取行业套餐 mergeIndustryMap := make(map[string]int, 0) for i := 0; i < serviceLen; i++ { industryName := serviceIndustryMap[serviceList[i].ContractServiceId] // 不需要合并的行业 if industryName == "" { fmt.Println("1:", serviceList[i]) mergeList = append(mergeList, serviceList[i]) continue } // 未合并则进行合并 if mergeIndustryMap[industryName] > 0 { continue } count := countIndustryMap[industryName] if count == 1 { // 取主/客观套餐 mergeList = append(mergeList, childrenServiceMap[industryName]) } else { // 0或者2都取行业套餐 mergeList = append(mergeList, industryServiceMap[industryName]) } mergeIndustryMap[industryName] += 1 } return } // CRM8.8-HandleEquityPermissionLookList 权益-权限展示的主客观合并处理 func HandleEquityPermissionLookList(permissionLookList []*company_report_permission.PermissionLookList) []*company_report_permission.PermissionLookList { if len(permissionLookList) <= 0 { return permissionLookList } checkList := permissionLookList[0].CheckList //fmt.Println(checkList) permissionList := permissionLookList[0].Items permissionLen := len(permissionList) if len(checkList) <= 0 || permissionLen <= 0 { return permissionLookList } // 若某个行业的主客观权限均被满足,则只留其中一个权限 // 1.取出每个行业对应的其中一个权限 industryName := []string{"医药", "消费", "科技", "智造"} namePermissionMap := make(map[string]*company_report_permission.PermissionLookItem) for i := 0; i < permissionLen; i++ { pName := permissionList[i].PermissionName if utils.InArrayByStr(industryName, pName) && namePermissionMap[pName] != nil { namePermissionMap[pName] = permissionList[i] } } // 2.计算哪些行业主客观权限都有 countIndustryMap := make(map[string]int, 0) for i := 0; i < permissionLen; i++ { p := permissionList[i] if utils.InArrayByStr(industryName, p.PermissionName) && utils.InArrayByInt(checkList, p.ChartPermissionId) { countIndustryMap[p.PermissionName] += 1 } } //fmt.Println(countIndustryMap) // 3.重新组成一个权限列表 mergeIndustryMap := make(map[string]int, 0) newPermissionList := make([]*company_report_permission.PermissionLookItem, 0) for i := 0; i < permissionLen; i++ { item := permissionList[i] if utils.InArrayByStr(industryName, item.PermissionName) { // 只有主客观之一, permissionName取remark if countIndustryMap[item.PermissionName] == 1 { item.PermissionName = item.Remark newPermissionList = append(newPermissionList, item) continue } // 主客观都有 if countIndustryMap[item.PermissionName] > 1 && mergeIndustryMap[item.PermissionName] == 0 { mergeIndustryMap[item.PermissionName] += 1 newPermissionList = append(newPermissionList, item) } } else { newPermissionList = append(newPermissionList, item) } } permissionLookList[0].Items = newPermissionList return permissionLookList }