package contract import ( "encoding/json" "errors" "fmt" "github.com/beego/beego/v2/client/orm" "github.com/shopspring/decimal" "hongze/hz_crm_api/models" "hongze/hz_crm_api/models/company" "hongze/hz_crm_api/models/contract" "hongze/hz_crm_api/models/contract/request" "hongze/hz_crm_api/models/system" "hongze/hz_crm_api/services" "hongze/hz_crm_api/utils" "mime/multipart" "os" "reflect" "regexp" "sort" "strconv" "strings" "time" ) // AddContract 新增合同 func AddContract(req request.AddContractReq, sellerId, productId int, sellerName string) (newContract *contract.Contract, err error, errMsg string) { originalPrice := req.OriginalPrice price := req.Price if originalPrice < 0 { err = errors.New("合同金额不能小于0") return } //如果优惠后金额小于等于0,那么就是等于优惠前的金额 if price <= 0 { price = originalPrice } //合同日期 var startDate, endDate time.Time if req.ContractBusinessType == "代付合同" { businessContractInfo, tmpErr := contract.GetContractById(req.RelationContractId) if tmpErr != nil { err = tmpErr return } startDate = businessContractInfo.StartDate endDate = businessContractInfo.EndDate ok, tmpErr := CheckContractPrice(businessContractInfo, price) if tmpErr != nil { err = tmpErr return } if !ok { err = errors.New("合同金额异常,不能高于业务合同金额") errMsg = "合同金额异常,不能高于业务合同金额" return } } else { tmpStartDate, tmpErr := time.ParseInLocation(utils.FormatDate, req.StartDate, time.Local) if tmpErr != nil { err = errors.New(fmt.Sprint("合同开始日期转换失败:", tmpErr)) return } startDate = tmpStartDate tmpEndDate, tmpErr := time.ParseInLocation(utils.FormatDate, req.EndDate, time.Local) if tmpErr != nil { err = errors.New(fmt.Sprint("合同结束日期转换失败:", tmpErr)) return } endDate = tmpEndDate } companyName := req.CompanyName if companyName == "" { err = errors.New("客户名称必填") return } creditCode := req.CreditCode if companyName == "" { err = errors.New("社会统一信用代码必填") return } contractCode, err := contract.GetCompanyContractCode(productId, req.ContractBusinessType) if err != nil { err = errors.New(fmt.Sprint("合同编号生成异常,Err:", err)) return } //权益的新签合同重新定义,如果合同起始时间在第一份新签合同起始日期 1年之内的,仍为新签合同。 if productId == utils.COMPANY_PRODUCT_RAI_ID && req.ContractType == "" { //根据社会信用码获取客户信息 companyInfo, tmpErr := company.GetCompanyByCreditCode(creditCode) //如果查询异常,且并不是在系统中找不到该社会信用码,那么就异常返回 if tmpErr != nil { err = errors.New(fmt.Sprint("根据社会信用码获取客户信息,Err:", tmpErr)) return } totalLastYear, tmpErr := GetCompanyContractCountRaiByLastYear(companyInfo.CompanyId, req.StartDate) if tmpErr != nil { err = errors.New(fmt.Sprint("获取第一份新签合同起始日期是否1年之内失败,Err:", tmpErr)) return } if totalLastYear > 0 { req.ContractType = "新签合同" } else { req.ContractType = "续约合同" } } contractInfo := &contract.Contract{ ContractCode: contractCode, SellerId: sellerId, SellerName: sellerName, ProductId: productId, ContractType: req.ContractType, ContractBusinessType: req.ContractBusinessType, Status: "待提交", StartDate: startDate, EndDate: endDate, OriginalPrice: originalPrice, Price: price, PayRemark: utils.TrimStr(req.PayRemark), //付款方式说明,长度255位 PayChannel: utils.TrimStr(req.PayChannel), //付款渠道,长度255位 CompanyName: utils.TrimStr(companyName), CreditCode: utils.TrimStr(creditCode), ProvinceId: req.ProvinceId, Province: utils.TrimStr(req.Province), CityId: req.CityId, City: utils.TrimStr(req.City), Address: utils.TrimStr(req.Address), Fax: utils.TrimStr(req.Fax), Phone: utils.TrimStr(req.Phone), Postcode: utils.TrimStr(req.Postcode), Remark: req.Remark, SellerRemark: req.SellerRemark, //销售备注 TemplateId: req.TemplateId, SourceId: req.SourceId, //来源合同id ModifyTime: time.Now(), CreateTime: time.Now(), } contractServiceSlice, err := getContractServiceAndDetail(contractInfo.ProductId, req.Service, true) if err != nil { return } newContract, err = contract.AddContract(contractInfo, contractServiceSlice, req.RelationContractId) if err != nil { return } //添加操作日志 remark := "新增合同模板" if newContract.SourceId > 0 { remark = "复制模板" } _ = contract.AddContractOperationRecord(newContract.ContractId, newContract.SellerId, 0, "add", newContract.SellerName, remark) return } // EditContract 编辑合同 func EditContract(req request.EditContractReq, opUser *system.Admin) (newContract *contract.Contract, err error, errMsg string) { //查询当前合同信息 nowContract, err := contract.GetContractById(req.ContractId) if err != nil { if err.Error() == utils.ErrNoRow() { err = errors.New(fmt.Sprint("根据合同编号:", req.ContractId, " 找不到初始合同")) } return } if nowContract.SellerId != opUser.AdminId { err = errors.New("当前账号无操作权限") return } ignoreStatus := []string{"待提交", "已撤回", "已驳回", "已审批"} if !strings.Contains(strings.Join(ignoreStatus, ","), nowContract.Status) { err = errors.New("合同状态异常,不允许修改,当前合同状态:" + nowContract.Status) return } originalPrice := req.OriginalPrice price := req.Price if originalPrice < 0 { err = errors.New("合同金额不能小于0") return } //如果优惠后金额小于等于0,那么就是等于优惠前的金额 if price <= 0 { price = originalPrice } checkPrice := price //代付合同,需要检查的需要支付的余额 // 是否更新业务合同金额 updateBusinessContractPrice := 0.0 if nowContract.Status == "已审批" && nowContract.ContractBusinessType == "代付合同" { updateBusinessContractPrice = nowContract.Price //因为当前代付合同是已审批的,所以修改重审的时候: //需要检查的需要支付的余额 = 当前提交的金额 - 之前提交的金额 checkPrice = price - nowContract.Price } //合同日期 var startDate, endDate time.Time if nowContract.ContractBusinessType == "代付合同" { businessContractInfo, tmpErr := contract.GetContractById(req.RelationContractId) if tmpErr != nil { err = tmpErr return } startDate = businessContractInfo.StartDate endDate = businessContractInfo.EndDate ok, tmpErr := CheckContractPrice(businessContractInfo, checkPrice) if tmpErr != nil { err = tmpErr return } if !ok { err = errors.New("合同金额异常,不能高于业务合同金额") errMsg = "合同金额异常,不能高于业务合同金额" return } } else { tmpStartDate, tmpErr := time.ParseInLocation(utils.FormatDate, req.StartDate, time.Local) if tmpErr != nil { err = errors.New(fmt.Sprint("合同开始日期转换失败:", tmpErr)) return } startDate = tmpStartDate tmpEndDate, tmpErr := time.ParseInLocation(utils.FormatDate, req.EndDate, time.Local) if tmpErr != nil { err = errors.New(fmt.Sprint("合同结束日期转换失败:", tmpErr)) return } endDate = tmpEndDate } companyName := utils.TrimStr(req.CompanyName) if companyName == "" { err = errors.New("客户名称必填") return } creditCode := utils.TrimStr(req.CreditCode) if companyName == "" { err = errors.New("社会统一信用代码必填") return } modifyContent := "" //变更记录 nowContract.ContractType = req.ContractType //合同类型 nowContract.StartDate = startDate //合同开始日期 nowContract.EndDate = endDate //合同结束日期 nowContract.OriginalPrice = originalPrice //原始金额 nowContract.Price = price //优惠后的金额 nowContract.PayRemark = utils.TrimStr(req.PayRemark) //付款方式说明,长度255位 nowContract.PayChannel = utils.TrimStr(req.PayChannel) //付款渠道,长度255位 nowContract.CompanyName = companyName //企业客户名称 nowContract.CreditCode = creditCode //组织社会信用代码 nowContract.ProvinceId = req.ProvinceId //省级id nowContract.Province = utils.TrimStr(req.Province) //省 nowContract.CityId = req.CityId //市级id nowContract.City = utils.TrimStr(req.City) //市 nowContract.Address = utils.TrimStr(req.Address) //详细地址 nowContract.Fax = utils.TrimStr(req.Fax) //传真 nowContract.Phone = utils.TrimStr(req.Phone) //电话 nowContract.FileUrl = "" //修改合同后,需要移除原有的合同附件 nowContract.Postcode = utils.TrimStr(req.Postcode) //邮编 nowContract.Remark = req.Remark //补充说明 nowContract.SellerRemark = req.SellerRemark //销售备注 nowContract.ModifyTime = time.Now() //更新时间 nowContract.Status = "待提交" //合同状态 //获取服务信息 contractServiceSlice, err := getContractServiceAndDetail(nowContract.ProductId, req.Service, true) if err != nil { return } //最近一次审批通过或者驳回的申请单 lastContractApproval, err := contract.GetLastContractApprovalByContractIdAndStatus(nowContract.ContractId, "contract") if err != nil && err.Error() != utils.ErrNoRow() { return } //如果有申请记录,且申请单的状态是已审批,那么审核内容是:修改重审 if lastContractApproval != nil { //旧的合同信息 var snapshotContract contract.ContractDetail jsonErr := json.Unmarshal([]byte(lastContractApproval.ContractDetail), &snapshotContract) if jsonErr != nil { err = jsonErr return } //applyContent = "修改重审" modifyContentStrList := make([]string, 0) //客户信息 updateCompanyInfoStrList := contrastCompanyInfo(snapshotContract, *nowContract) if len(updateCompanyInfoStrList) > 0 { updateCompanyInfoStr := `` if len(updateCompanyInfoStrList) == 1 { updateCompanyInfoStr = fmt.Sprint("客户信息发生了变化:" + updateCompanyInfoStrList[0]) } else { updateCompanyInfoStr = fmt.Sprint("客户信息发生了变化:", strings.Join(updateCompanyInfoStrList, "")) } modifyContentStrList = append(modifyContentStrList, updateCompanyInfoStr) } //金额、付款、合同日期方式 updatePayInfoStrList := contrastPayInfo(snapshotContract, *nowContract) modifyContentStrList = append(modifyContentStrList, updatePayInfoStrList...) if len(modifyContentStrList) > 0 { modifyContent = strings.Join(updatePayInfoStrList, "
") } //服务内容 updateServiceStr, tmpErr := contrastServiceInfo(snapshotContract, contractServiceSlice) if tmpErr != nil { err = tmpErr return } if updateServiceStr != "" { modifyContentStrList = append(modifyContentStrList, updateServiceStr) } //补充内容 if nowContract.Remark != snapshotContract.Remark { snapshotContractRemark := snapshotContract.Remark if snapshotContractRemark == "" { snapshotContractRemark = "无" } nowContractRemark := nowContract.Remark if nowContractRemark == "" { nowContractRemark = "无" } updateStr := fmt.Sprint("原补充内容:", snapshotContractRemark, "现补充内容:", nowContractRemark) modifyContentStrList = append(modifyContentStrList, updateStr) } if len(modifyContentStrList) > 0 { modifyContent = strings.Join(modifyContentStrList, "
") } } nowContract.ModifyContent = modifyContent //修改信息 updateDetailCol := []string{"ContractType", "StartDate", "EndDate", "OriginalPrice", "Price", "PayRemark", "PayChannel", "CompanyName", "CreditCode", "ProvinceId", "Province", "CityId", "City", "Address", "Fax", "Phone", "FileUrl", "Postcode", "Remark", "SellerRemark", "ModifyContent", "ModifyTime", "Status"} //修改合同 err = contract.EditContract(nowContract, updateDetailCol, contractServiceSlice, req.RelationContractId) //添加操作日志 remark := "编辑合同模板" _ = contract.AddContractOperationRecord(nowContract.ContractId, nowContract.SellerId, 0, "edit", nowContract.SellerName, remark) //修改业务合同的已支付金额 if updateBusinessContractPrice > 0 { go updateContractPaidPriceByPaymentOnBehalfContractId(nowContract.ContractId, -nowContract.Price) } //赋值返回 newContract = nowContract return } // contrastCompanyInfo 比对客户信息是否变更 func contrastCompanyInfo(snapshotContract contract.ContractDetail, nowContract contract.Contract) (updateStrList []string) { //客户信息比对 if nowContract.CompanyName != snapshotContract.CompanyName { updateStrList = append(updateStrList, fmt.Sprint("原客户名称:", snapshotContract.CompanyName, "现客户名称:", nowContract.CompanyName)) } if nowContract.CreditCode != snapshotContract.CreditCode { updateStrList = append(updateStrList, fmt.Sprint("原社会信用码:", snapshotContract.CreditCode, "现社会信用码:", nowContract.CreditCode)) } if nowContract.Province != snapshotContract.Province || nowContract.City != snapshotContract.City { updateStrList = append(updateStrList, fmt.Sprint("原公司地址:", snapshotContract.Province, snapshotContract.City, "现公司地址:", nowContract.Province, nowContract.City)) } if nowContract.Address != snapshotContract.Address { snapshotContractAddress := snapshotContract.Address if snapshotContractAddress == "" { snapshotContractAddress = `无` } nowContractAddress := nowContract.Address if nowContractAddress == "" { nowContractAddress = `无` } updateStrList = append(updateStrList, fmt.Sprint("原详细地址:", snapshotContractAddress, "现详细地址:", nowContractAddress)) } if nowContract.Fax != snapshotContract.Fax { snapshotContractFax := snapshotContract.Fax if snapshotContractFax == "" { snapshotContractFax = `无` } nowContractFax := nowContract.Fax if nowContractFax == "" { nowContractFax = `无` } updateStrList = append(updateStrList, fmt.Sprint("原传真:", snapshotContractFax, "现传真:", nowContractFax)) } if nowContract.Phone != snapshotContract.Phone { snapshotContractPhone := snapshotContract.Phone if snapshotContractPhone == "" { snapshotContractPhone = `无` } nowContractPhone := nowContract.Phone if nowContractPhone == "" { nowContractPhone = `无` } updateStrList = append(updateStrList, fmt.Sprint("原电话:", snapshotContractPhone, "现电话:", nowContractPhone)) } if nowContract.Postcode != snapshotContract.Postcode { snapshotContractPostcode := snapshotContract.Postcode if snapshotContractPostcode == "" { snapshotContractPostcode = `无` } nowContractPostcode := nowContract.Postcode if nowContractPostcode == "" { nowContractPostcode = `无` } updateStrList = append(updateStrList, fmt.Sprint("原邮编:", snapshotContractPostcode, "现邮编:", nowContractPostcode)) } return } // contrastPayInfo 比对合同金额、付款方式是否变更 func contrastPayInfo(snapshotContract contract.ContractDetail, nowContract contract.Contract) (updateStrList []string) { //合同信息比对 if nowContract.StartDate != snapshotContract.StartDate || nowContract.EndDate != snapshotContract.EndDate { updateStrList = append(updateStrList, fmt.Sprint("原合同期限:", snapshotContract.StartDate.Format(utils.FormatDate), " ~ ", snapshotContract.EndDate.Format(utils.FormatDate), "现合同期限:", nowContract.StartDate.Format(utils.FormatDate), " ~ ", nowContract.EndDate.Format(utils.FormatDate))) } if nowContract.ContractBusinessType == "代付合同" { if nowContract.Price != snapshotContract.Price { updateStrList = append(updateStrList, fmt.Sprint("原代付金额:", decimal.NewFromFloat(snapshotContract.Price).String(), "现代付金额:", decimal.NewFromFloat(nowContract.Price).String())) } } else { if nowContract.OriginalPrice != snapshotContract.OriginalPrice { updateStrList = append(updateStrList, fmt.Sprint("原合同金额:", decimal.NewFromFloat(snapshotContract.OriginalPrice).String(), "现合同金额:", decimal.NewFromFloat(nowContract.OriginalPrice).String())) } if nowContract.Price != snapshotContract.Price { updateStrList = append(updateStrList, fmt.Sprint("原优惠后金额:", decimal.NewFromFloat(snapshotContract.Price).String(), "现优惠后金额:", decimal.NewFromFloat(nowContract.Price).String())) } } if nowContract.PayRemark != snapshotContract.PayRemark { snapshotContractInfo := snapshotContract.PayRemark if snapshotContractInfo == "" { snapshotContractInfo = "无" } nowContractInfo := nowContract.PayRemark if nowContractInfo == "" { nowContractInfo = "无" } updateStrList = append(updateStrList, fmt.Sprint("原付款方式:", snapshotContractInfo, "现付款方式:", nowContractInfo)) } if nowContract.PayChannel != snapshotContract.PayChannel { snapshotContractInfo := snapshotContract.PayChannel if snapshotContractInfo == "" { snapshotContractInfo = "无" } nowContractInfo := nowContract.PayChannel if nowContractInfo == "" { nowContractInfo = "无" } updateStrList = append(updateStrList, fmt.Sprint("原付款方:", snapshotContractInfo, "现付款方:", nowContractInfo)) } return } // contrastServiceInfo 比对合同服务内容是否变更 func contrastServiceInfo(snapshotContract contract.ContractDetail, contractServiceSlice []*contract.ContractServiceAndDetail) (updateStr string, err error) { serviceList := snapshotContract.Service nowServiceList := contractServiceSlice // CRM8.8-权益的合同服务主客观合并 if snapshotContract.ProductId == 2 { updateStr = handleRaiContractModifyContentByServices(serviceList, nowServiceList) return } snapshotPermissionList, err := GetPermissionByContractService(snapshotContract.ProductId, serviceList) if err != nil { return } allPermissionMap := make(map[int]string) snapshotPermissionIdList := make([]int, 0) for _, permissionItem := range snapshotPermissionList { for _, permission := range permissionItem.Items { allPermissionMap[permission.ChartPermissionId] = permission.PermissionName if snapshotContract.ProductId == 2 { allPermissionMap[permission.ChartPermissionId] = permission.Remark } } snapshotPermissionIdList = append(snapshotPermissionIdList, permissionItem.CheckList...) } if len(snapshotPermissionIdList) > 0 { sort.Ints(snapshotPermissionIdList) } nowPermissionList, err := GetPermissionByContractService(snapshotContract.ProductId, nowServiceList) if err != nil { return } nowPermissionIdList := make([]int, 0) for _, permissionItem := range nowPermissionList { nowPermissionIdList = append(nowPermissionIdList, permissionItem.CheckList...) } if len(nowPermissionIdList) > 0 { sort.Ints(nowPermissionIdList) } //长度不等 if len(snapshotPermissionIdList) != len(nowPermissionIdList) { goto FalseContrast } for i := 0; i < len(snapshotPermissionIdList); i++ { if snapshotPermissionIdList[i] != nowPermissionIdList[i] { //权限id不匹配 goto FalseContrast } } return FalseContrast: snapshotContractServiceStrList := make([]string, 0) for _, id := range snapshotPermissionIdList { if permissionName, ok := allPermissionMap[id]; ok { snapshotContractServiceStrList = append(snapshotContractServiceStrList, permissionName) } } nowContractServiceStrList := make([]string, 0) for _, id := range nowPermissionIdList { if permissionName, ok := allPermissionMap[id]; ok { nowContractServiceStrList = append(nowContractServiceStrList, permissionName) } } snapshotContractServiceStr := `无` if len(snapshotContractServiceStrList) > 0 { snapshotContractServiceStr = strings.Join(snapshotContractServiceStrList, ",") } nowContractServiceStr := `无` if len(nowContractServiceStrList) > 0 { nowContractServiceStr = strings.Join(nowContractServiceStrList, ",") } updateStr = fmt.Sprint("原服务内容:", snapshotContractServiceStr, "现服务内容:", nowContractServiceStr) return } // DeleteContract 删除合同 func DeleteContract(contractId int, opUser *system.Admin) (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 { err = errors.New("当前账号无操作权限") return } ignoreStatus := []string{"已审批", "待审批"} if strings.Contains(strings.Join(ignoreStatus, ","), nowContract.Status) { err = errors.New("合同状态异常,不允许删除,当前合同状态:" + nowContract.Status) return } //如果删除状态 >0,那么代表已经被删除了 if nowContract.IsDelete > 0 { err = errors.New("该合同已删除") return } //假删除 err = contract.DeleteContract(nowContract) if err != nil { return } //添加操作日志 //remark := "编辑合同模板" //_ = contract.AddContractOperationRecord(nowContract.ContractId, nowContract.SellerId, 0, "edit", nowContract.SellerName, remark) return } // InvalidContract 作废合同 func InvalidContract(contractId int, opUser *system.Admin) (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.AddContractOperationRecord(nowContract.ContractId, opUser.AdminId, 0, "invalid", opUser.AdminName, remark) //修改业务合同的已支付金额 if nowContract.ContractBusinessType == "代付合同" { go updateContractPaidPriceByPaymentOnBehalfContractId(nowContract.ContractId, -nowContract.Price) } return } // UploadFile 上传更新合同附件 func UploadFile(contractId int, ext string, fileMulti multipart.File, opUser *system.Admin) (err error) { //获取合同信息 contractInfo, err := contract.GetContractById(contractId) if err != nil { return } //合同状态判断 if contractInfo.Status != "已审批" { err = errors.New("合同状态异常,不允许更新合同附件,当前合同状态:" + contractInfo.Status) return } if contractInfo.SellerId != opUser.AdminId { err = errors.New("合同异常,只允许本人更新合同附件") 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.FileUrl = resourceUrl contractInfo.ModifyTime = time.Now() err = contractInfo.Update([]string{"FileUrl", "ModifyTime"}) if err != nil { return } //添加操作日志 remark := "更新合同附件" _ = contract.AddContractOperationRecord(contractInfo.ContractId, opUser.AdminId, 0, "update_file", opUser.RealName, remark) return } // UploadCheckBackFile 上传签回合同附件 func UploadCheckBackFile(contractId int, ext string, fileMulti multipart.File, opUser *system.Admin) (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.AddContractOperationRecord(contractInfo.ContractId, opUser.AdminId, 0, "upload", opUser.RealName, remark) return } // UploadRescindFile 上传解约合同附件 func UploadRescindFile(contractId int, ext string, fileMulti multipart.File, opUser *system.Admin) (err error) { //获取合同信息 contractInfo, err := contract.GetContractById(contractId) if err != nil { return } //合同状态判断 if 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.RescindFileUrl = resourceUrl contractInfo.Status = "已解约" contractInfo.ModifyTime = time.Now() contractInfo.RescindTime = time.Now() err = contractInfo.Update([]string{"RescindFileUrl", "Status", "ModifyTime", "RescindTime"}) if err != nil { return } //添加操作日志 remark := "上传解约合同附件" _ = contract.AddContractOperationRecord(contractInfo.ContractId, opUser.AdminId, 0, "rescind", opUser.RealName, remark) //修改业务合同的已支付金额 if contractInfo.ContractBusinessType == "代付合同" { go updateContractPaidPriceByPaymentOnBehalfContractId(contractInfo.ContractId, -contractInfo.Price) } return } // 根据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.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.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 := getContractServiceAndDetailList(contractId) if err != nil { err = errors.New(fmt.Sprint("查找合同服务异常", err)) return } contractDetail.Service = serviceList return } // getContractServiceAndDetailList 根据合同Id获取服务详情列表 func getContractServiceAndDetailList(contractId int) (serviceList []*contract.ContractServiceAndDetail, err error) { serviceList, err = contract.GetContractServiceAndDetailList(contractId) if err != nil { err = errors.New(fmt.Sprint("查找合同服务异常", err)) return } // 权益合同主客观合并 //if mergeEquity && len(serviceList) > 0 && serviceList[0].ProductId == 2 { // mergeList, e := EquityMergeSubjectAndObject(serviceList) // if e != nil { // err = errors.New(fmt.Sprint("合并权益合同服务异常", err)) // return // } // serviceList = mergeList //} newLen := len(serviceList) for i := 0; newLen > i; i++ { if serviceList[i].HasDetail == "是" { list, detailErr := contract.GetContractServiceDetailListByServiceId(serviceList[i].ContractServiceId) if detailErr != nil { err = errors.New(fmt.Sprint("查找合同服务详情异常", detailErr)) return } serviceList[i].DetailList = list } } return } // GetContractDetailByAddContractReq 根据请求参数获取合同详情结构体数据 func GetContractDetailByAddContractReq(req request.AddContractReq, sellerId, productId int, sellerName string) (contractDetail *contract.ContractDetail, err error) { originalPrice := req.OriginalPrice price := req.Price if originalPrice < 0 { err = errors.New("合同金额不能小于0") return } //如果优惠后金额小于等于0,那么就是等于优惠前的金额 if price <= 0 { price = originalPrice } companyName := req.CompanyName if companyName == "" { err = errors.New("客户名称必填") return } creditCode := req.CreditCode if companyName == "" { err = errors.New("社会统一信用代码必填") return } contractCode, err := contract.GetCompanyContractCode(productId, req.ContractBusinessType) if err != nil { err = errors.New(fmt.Sprint("合同编号生成异常,Err:", err)) return } //校验合同模板类型 contractTemplate, err := contract.GetContractTemplateByTemplateId(req.TemplateId) if err != nil { return } if contractTemplate.ProductId != productId { err = errors.New("模板类型与当前账户类型不符") return } contractDetail = &contract.ContractDetail{ ContractId: int(time.Now().Unix()), ContractCode: contractCode, SellerId: sellerId, SellerName: sellerName, ProductId: productId, ContractBusinessType: req.ContractBusinessType, ContractType: req.ContractType, Status: "待提交", OriginalPrice: originalPrice, Price: price, PayRemark: req.PayRemark, //付款方式说明,长度255位 PayChannel: req.PayChannel, //付款渠道,长度255位 CompanyName: companyName, CreditCode: creditCode, ProvinceId: req.ProvinceId, Province: req.Province, CityId: req.CityId, City: req.City, Address: req.Address, Fax: req.Fax, Phone: req.Phone, Postcode: req.Postcode, Remark: req.Remark, TemplateId: req.TemplateId, SourceId: req.SourceId, //来源合同id ModifyTime: time.Now(), CreateTime: time.Now(), } //合同日期 if req.ContractBusinessType == "代付合同" { //关联合同 relationContractDetailList := make([]*contract.ContractDetail, 0) tmpContractDetail, tmpErr := getContractDetail(req.RelationContractId) if tmpErr != nil { err = errors.New("查询业务关联合同详情异常:" + tmpErr.Error()) return } relationContractDetailList = append(relationContractDetailList, tmpContractDetail) contractDetail.RelationContractDetailList = relationContractDetailList } else { tmpStartDate, tmpErr := time.Parse(utils.FormatDate, req.StartDate) if tmpErr != nil { err = errors.New(fmt.Sprint("合同开始日期转换失败:", tmpErr)) return } contractDetail.StartDate = tmpStartDate tmpEndDate, tmpErr := time.Parse(utils.FormatDate, req.EndDate) if tmpErr != nil { err = errors.New(fmt.Sprint("合同结束日期转换失败:", tmpErr)) return } contractDetail.EndDate = tmpEndDate contractServiceSlice, tmpErr := getContractServiceAndDetail(productId, req.Service, false) if tmpErr != nil { err = tmpErr return } contractDetail.Service = contractServiceSlice } return } // 根据请求数据获取套餐服务详情信息 func getContractServiceAndDetail(productId int, reqService []request.AddContractServiceReq, base642Image bool) (contractServiceSlice []*contract.ContractServiceAndDetail, err error) { contractServiceSlice = make([]*contract.ContractServiceAndDetail, 0) if len(reqService) < 0 { err = errors.New("请至少选择一种套餐") return } for i := 0; i < len(reqService); i++ { item := reqService[i] detail := item.Detail contractServiceDetailSlice := make([]*contract.ContractServiceDetail, 0) if len(detail) > 0 { for j := 0; j < len(detail); j++ { detailItem := detail[j] cellMap := make(map[string]string) for k := 0; k < len(detailItem); k++ { key := fmt.Sprint("cell_", k+1) tmpVal, jsonErr := json.Marshal(detailItem[k]) if jsonErr != nil { err = errors.New(fmt.Sprint("json转换失败:", jsonErr)) return } cellMap[key] = string(tmpVal) } contractServiceDetail := &contract.ContractServiceDetail{ Col1: func(cellMap map[string]string) string { tmpVal, ok := cellMap["cell_1"] if ok { return tmpVal } else { return "" } }(cellMap), Col2: func(cellMap map[string]string) string { tmpVal, ok := cellMap["cell_2"] if ok { return tmpVal } else { return "" } }(cellMap), Col3: func(cellMap map[string]string) string { tmpVal, ok := cellMap["cell_3"] if ok { return tmpVal } else { return "" } }(cellMap), Col4: func(cellMap map[string]string) string { tmpVal, ok := cellMap["cell_4"] if ok { return tmpVal } else { return "" } }(cellMap), Col5: func(cellMap map[string]string) string { tmpVal, ok := cellMap["cell_5"] if ok { return tmpVal } else { return "" } }(cellMap), Col6: func(cellMap map[string]string) string { tmpVal, ok := cellMap["cell_6"] if ok { return tmpVal } else { return "" } }(cellMap), Col7: func(cellMap map[string]string) string { tmpVal, ok := cellMap["cell_7"] if ok { return tmpVal } else { return "" } }(cellMap), ServiceTemplateId: item.ServiceTemplateId, CreateTime: time.Now(), } contractServiceDetailSlice = append(contractServiceDetailSlice, contractServiceDetail) } } hasDetail := "否" if len(contractServiceDetailSlice) > 0 { hasDetail = "是" } //报价单图片地址 valueStr := item.Value if base642Image { b, _ := regexp.MatchString(`^data:\s*image\/(\w+);base64,`, valueStr) if b { imageUrl, uploadErr := UploadImageBase64(valueStr) if uploadErr != nil { err = errors.New(fmt.Sprint("base64图片上传失败:", uploadErr)) return } valueStr = imageUrl } } //寻找该系统模板 systemContractServiceTem, tmpErr := contract.GetContractServiceTemplateById(item.ServiceTemplateId) if tmpErr != nil { err = errors.New("找不到该模板") return } tmpContractService := &contract.ContractServiceAndDetail{ ServiceTemplateId: item.ServiceTemplateId, Title: item.Title, Value: valueStr, ProductId: productId, //CreateTime: time.Now(), HasDetail: hasDetail, TableValue: systemContractServiceTem.TableValue, DetailList: contractServiceDetailSlice, ChartPermissionId: systemContractServiceTem.ChartPermissionId, } contractServiceSlice = append(contractServiceSlice, tmpContractService) } return } // 获取品种列数据(因为前端可以随意插入列数据,所以需要根据列名来搜索对应的品种列) func GetProductCelData(detail contract.ContractServiceDetail, tableCel *request.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 } // 将base64的图片上传至oss func UploadImageBase64(base64Str string) (resourceUrl string, err error) { ext := ".png" uploadDir := "./static" randStr := utils.GetRandStringNoSpecialChar(28) fileName := randStr + ext fpath := uploadDir + "/" + fileName b, _ := regexp.MatchString(`^data:\s*image\/(\w+);base64,`, base64Str) if !b { err = errors.New("图片格式不正确") return } re, _ := regexp.Compile(`^data:\s*image\/(\w+);base64,`) base64Str = re.ReplaceAllString(base64Str, "") base64Str = strings.Replace(base64Str, " ", "", -1) base64Str = strings.Replace(base64Str, " ", "", -1) //imgByte, err := base64.StdEncoding.DecodeString(base64Str) //err=ioutil.WriteFile(fpath,imgByte,os.ModeAppend) //if err!=nil { // br.Msg = "图片保存失败" // br.ErrMsg = "图片保存失败,Err:"+err.Error() // return //} err = utils.SaveBase64ToFile(base64Str, fpath) if err != nil { return } fmt.Println("end") defer os.Remove(fpath) savePath := utils.Upload_Audio_Dir + time.Now().Format("200601/20060102/") savePath += fileName //上传到阿里云 err = services.UploadVideoAliyun(fileName, fpath, savePath) if err != nil { return } utils.FileLog.Info("%s:", time.Now().Format(utils.FormatDateTime)) utils.FileLog.Info("end update oss ") resourceUrl = utils.Imghost + savePath item := new(models.Resource) item.ResourceUrl = resourceUrl item.ResourceType = 1 item.CreateTime = time.Now() _, err = models.AddResource(item) if err != nil { return } return } // GetPermissionByContractService 通过合同服务,获取权限id列表 func GetPermissionByContractService(productId int, serviceList []*contract.ContractServiceAndDetail) (permissionList []*company.PermissionLookList, err error) { //获取已经勾选的的权限 checkPermissionIdMap, err := GetServicePermissionMap(serviceList) if err != nil { return } permissionList, err = GetPermissionByPermissionIdMap(productId, checkPermissionIdMap) return } // GetPermissionByPermissionIdMap 通过权限id的map,获取权限列表 func GetPermissionByPermissionIdMap(productId int, checkPermissionIdMap map[int]int) (permissionList []*company.PermissionLookList, err error) { //子权限切片集合 allPermissions, err := company.GetPermissionLookItemsByProductId(productId) if err != nil { err = fmt.Errorf("获取权限失败,Err:%s", err.Error()) return } permissionMap := make(map[int][]*company.PermissionLookItem, 0) for _, v := range allPermissions { if v.ParentId > 0 { permissionMap[v.ParentId] = append(permissionMap[v.ParentId], v) } } //遍历获取 for _, v := range allPermissions { if v.ParentId == 0 { checkList := make([]int, 0) plist := new(company.PermissionLookList) plist.Items = make([]*company.PermissionLookItem, 0) items, ok1 := permissionMap[v.ChartPermissionId] if ok1 { for _, n := range items { if _, ok := checkPermissionIdMap[n.ChartPermissionId]; ok { checkList = append(checkList, n.ChartPermissionId) } else if _, ok2 := checkPermissionIdMap[n.ChartPermissionId+utils.PERMISSION_ID_UPGRADE]; ok2 { checkList = append(checkList, n.ChartPermissionId) n.IsUpgrade = 1 } } plist.Items = items } plist.ClassifyName = v.PermissionName plist.CheckList = checkList permissionList = append(permissionList, plist) } } return } // GetServicePermissionMap 获取合同服务中的权限id map func GetServicePermissionMap(serviceList []*contract.ContractServiceAndDetail) (checkPermissionIdMap map[int]int, err error) { checkPermissionIdMap = make(map[int]int) //获取已经勾选的的权限 for _, contractService := range serviceList { //如果是权益,那么研选必要(2022-07-06 10:29:11移除) //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.GetPermissionLookItemsByProductId(utils.COMPANY_PRODUCT_FICC_ID) if e != nil { err = fmt.Errorf("获取权限失败 Err:%v", e) return } permissionMap := make(map[int][]*company.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 } } } } case 2: //ficc小套餐 permissionValues := []string{ "FICC周报", "商品双周报+线上电话会讨论会
(由弘则的研究员主持线上讨论)", "数据点评", } for _, detail := range contractService.DetailList { var tableCel request.AddContractServiceDetailReq tmpErr := json.Unmarshal([]byte(detail.Col1), &tableCel) if tmpErr != nil { err = tmpErr return } if strings.Contains(strings.Join(permissionValues, ","), tableCel.Value) { //获取品种列数据 var tableCel2 request.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{"权益"} permissionFilterrr := []string{"固收", "路演服务", "研选扣点包", "调研", "专家", "研选订阅"} //不在大套餐中展示的权益权限 for _, v := range permissionFiccClassifyArr { items, tmpErr := company.GetPermissionLookItems(2, v) if tmpErr != nil { err = tmpErr return } for _, n := range items { //如果是专家行业,那么 结束当前循环,进入下一循环(产品需求:专家行业不在里面) //if n.ChartPermissionId == 29 || n.ChartPermissionId == 31 { // continue //} if utils.InArrayByStr(permissionFilterrr, n.PermissionName) { continue } checkPermissionIdMap[n.ChartPermissionId] = n.ChartPermissionId } } } } return } // GetServicePackageType 获取合同服务中的 大小套餐类型 func GetServicePackageType(serviceList []*contract.ContractServiceAndDetail) (packageType int, err error) { //获取已经勾选的的权限 for _, contractService := range serviceList { switch contractService.ServiceTemplateId { case 1: //ficc 大套餐 packageType = 1 case 2: //ficc小套餐 packageType = 2 case 4, 5, 6: //权益大套餐 //packageType = 1 } } return } // GetRaiServicePackageType 获取合同服务中的 权益的大小套餐类型 func GetRaiServicePackageType(serviceList []*contract.ContractServiceAndDetail) (raiPackageType int) { for _, contractService := range serviceList { switch contractService.ServiceTemplateId { case 5: // 45w大套餐 raiPackageType = 2 case 6: // 70w大套餐 raiPackageType = 1 } if raiPackageType > 0 { break } } return } // CheckContractPrice 校验代付合同金额是否 大于 业务合同金额(可能存在多份合同,需要遍历,如果大于的话,校验不通过,需要驳回) func CheckContractPrice(contractInfo *contract.Contract, price float64) (ok bool, err error) { list, err := contract.GetContractRelationListByContractId(contractInfo.ContractId) if err != nil { return } payedPrice := 0.0 for _, v := range list { payedPrice += v.Price } if (contractInfo.Price - payedPrice) < price { return } ok = true return } // UploadCheckBackFileFromSeal 更新用印上传签回合同附件 func UploadCheckBackFileFromSeal(contractId int, fileUrl string, opUser *system.Admin) (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.AddContractOperationRecord(contractInfo.ContractId, opUser.AdminId, 0, "upload", opUser.RealName, remark) return } //func init() { // fmt.Println("contract init start") // go FixEquityContractService() // fmt.Println("contract init end") //} // FixEquityContractService 修复权益合同服务内容-CRM8.8 func FixEquityContractService() (err error) { defer func() { if err != nil { fmt.Println("FixEquityContractService Err: " + err.Error()) } }() // 获取所有权益的合同(不考虑状态) productId := 2 contractList, e := contract.GetContractListByProductId(productId) if e != nil { err = errors.New("获取权益合同列表失败") return } contractLen := len(contractList) if contractLen == 0 { fmt.Println("无合同需要修复") return } fmt.Println("待修复权益合同数", contractLen) //return // 合同IDs contractIdArr := make([]string, 0) contractIdServices := make(map[int][]*contract.ContractService, 0) for i := 0; i < contractLen; i++ { contractIdArr = append(contractIdArr, strconv.Itoa(contractList[i].ContractId)) newServices := make([]*contract.ContractService, 0) contractIdServices[contractList[i].ContractId] = newServices } contractIds := strings.Join(contractIdArr, ",") // 合同服务内容 serviceList, e := contract.GetContractServiceListByIds(contractIds) if e != nil { err = errors.New("获取权益合同服务内容列表失败") return } servicesLen := len(serviceList) if servicesLen == 0 { fmt.Println("无合同服务需要修复") return } for i := 0; i < servicesLen; i++ { contractIdServices[serviceList[i].ContractId] = append(contractIdServices[serviceList[i].ContractId], serviceList[i]) } // 服务套餐模板 templateList, e := contract.GetAllContractServiceTemplateList() if e != nil { err = errors.New("获取服务套餐模板列表失败") return } // 主客观服务套餐 titleArr := []string{"医药", "消费", "科技", "智造"} subTempMap := make(map[string]*contract.ContractServiceTemplate, 0) objTempMap := make(map[string]*contract.ContractServiceTemplate, 0) templateIdMap := make(map[int]*contract.ContractServiceTemplate, 0) templateLen := len(templateList) for i := 0; i < templateLen; i++ { templateIdMap[templateList[i].ServiceTemplateId] = templateList[i] } for i := 0; i < templateLen; i++ { if templateList[i].Title == "主观" { parentTemp := templateIdMap[templateList[i].Pid] subTempMap[parentTemp.Title] = templateList[i] continue } if templateList[i].Title == "客观" { parentTemp := templateIdMap[templateList[i].Pid] objTempMap[parentTemp.Title] = templateList[i] continue } } // 遍历合同 for i := 0; i < contractLen; i++ { contractId := contractList[i].ContractId fmt.Printf("正在修复第%d个, 合同ID: %d\n", i+1, contractId) // 合同服务内容 contractServices := contractIdServices[contractId] insertArr := make([]*contract.ContractService, 0) serviceLen := len(contractServices) // 是否含有医药、消费、科技、智造 for _, v := range titleArr { for ii := 0; ii < serviceLen; ii++ { createTime := contractServices[ii].CreateTime // 含有四种套餐之一 if contractServices[ii].Title == v { template := templateIdMap[contractServices[ii].ServiceTemplateId] pid := template.ServiceTemplateId insertSubject := true insertObject := true // 去重, 校验是否已存在主客观 for iii := 0; iii < serviceLen; iii++ { t := templateIdMap[contractServices[iii].ServiceTemplateId] if t.Pid == pid && t.Title == "主观" { insertSubject = false continue } if t.Pid == pid && t.Title == "客观" { insertObject = false continue } } if insertSubject { subTemp := subTempMap[v] title := v + "(" + subTemp.Title + ")" insertArr = append(insertArr, &contract.ContractService{ ContractId: contractId, ProductId: productId, ServiceTemplateId: subTemp.ServiceTemplateId, Title: title, Value: subTemp.Value, TableValue: subTemp.TableValue, HasDetail: "否", ChartPermissionId: subTemp.ChartPermissionId, CreateTime: createTime, }) } if insertObject { objTemp := objTempMap[v] title := v + "(" + objTemp.Title + ")" insertArr = append(insertArr, &contract.ContractService{ ContractId: contractId, ProductId: productId, ServiceTemplateId: objTemp.ServiceTemplateId, Title: title, Value: objTemp.Value, TableValue: objTemp.TableValue, HasDetail: "否", ChartPermissionId: objTemp.ChartPermissionId, CreateTime: createTime, }) } break } } } // 新增主客观 if len(insertArr) > 0 { if e := contract.MultiCreateContractService(insertArr); e != nil { fmt.Printf("第%d个修复失败, 合同ID: %d, Err: %s\n", i+1, contractId, e.Error()) return } fmt.Printf("第%d个修复成功, 合同ID: %d\n", i+1, contractId) } else { fmt.Printf("第%d个已修复过, 忽略合同ID: %d\n", i+1, contractId) } } return } // CRM8.8-权益合同主客观套餐合并 func EquityMergeSubjectAndObject(serviceList []*contract.ContractServiceAndDetail) (mergeList []*contract.ContractServiceAndDetail) { serviceLen := len(serviceList) if serviceLen == 0 { return serviceList } mergeArr := []string{"医药", "消费", "科技", "智造"} // 获取模板列表 templateList, e := contract.GetAllContractServiceTemplateList() if e != nil { return serviceList } parentTempMap := make(map[string]int, 0) templateMap := make(map[int]*contract.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]*contract.ContractServiceAndDetail, 0) childrenServiceMap := make(map[string]*contract.ContractServiceAndDetail, 0) for i := 0; i < serviceLen; i++ { temp := templateMap[serviceList[i].ServiceTemplateId] if temp == nil { continue } // 行业套餐 if utils.InArrayByStr(mergeArr, temp.Title) { serviceIndustryMap[i] = 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[i] = parentTemp.Title childrenServiceMap[parentTemp.Title] = serviceList[i] } } mergeList = make([]*contract.ContractServiceAndDetail, 0) // 遍历每一个套餐, 取出所属的行业, 不属于合并的行业则直接加入数组 // 属于合并的行业, 则校验行业子套餐数, 若子套餐数为1, 则取取主/客观套餐, 否则取行业套餐 mergeIndustryMap := make(map[string]int, 0) for i := 0; i < serviceLen; i++ { industryName := serviceIndustryMap[i] // 不需要合并的行业 if industryName == "" { 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-权益合同主客观权限的合并 func EquityMergeSubjectAndObjectPermission(list []*company.CompanyContractPermissionName) (newList []*company.CompanyContractPermissionName) { if len(list) == 0 { return list } // contractPermissionMap示例: // map[ // 665:map[ // 专家:[0xc0002e24d0] // 买方研选:[0xc0002e2630] // 医药:[0xc0002e2370 0xc0002e28f0] // 智造:[0xc0002e2160 0xc0002e26e0] // 消费:[0xc0002e22c0 0xc0002e2840] // 科技:[0xc0002e2210 0xc0002e2790] // 策略:[0xc0002e2420] // 路演服务:[0xc0002e2580] // ] // 666:map[ // 智造:[0xc0002e29a0 0xc0002e2b00] // 科技:[0xc0002e2a50 0xc0002e2bb0] // ] // ] contractPermissionMap := make(map[int]map[string][]*company.CompanyContractPermissionName) for _, v := range list { permissionMap, ok := contractPermissionMap[v.CompanyContractId] if ok { permissionItemMap, ok2 := permissionMap[v.ChartPermissionName] if !ok2 { permissionItemMap = make([]*company.CompanyContractPermissionName, 0) } permissionItemMap = append(permissionItemMap, v) permissionMap[v.ChartPermissionName] = permissionItemMap } else { permissionMap = make(map[string][]*company.CompanyContractPermissionName) permissionMap[v.ChartPermissionName] = append(permissionMap[v.ChartPermissionName], v) } contractPermissionMap[v.CompanyContractId] = permissionMap } newList = make([]*company.CompanyContractPermissionName, 0) for _, v := range contractPermissionMap { for _, p := range v { if len(p) == 1 { p[0].ChartPermissionName = p[0].PermissionRemark } newList = append(newList, p[0]) } } return } // HandleEquityPermissionLookList 权益-PermissionLookList主客观合并 func HandleEquityPermissionLookList(permissionLookList []*company.PermissionLookList) []*company.PermissionLookList { if len(permissionLookList) == 0 { return permissionLookList } checkList := permissionLookList[0].CheckList permissionList := permissionLookList[0].Items newPermissionList := HandleEquityPermissionLookItem(checkList, permissionList) permissionLookList[0].Items = newPermissionList return permissionLookList } // HandleEquityContractPermissionList 权益-ContractPermissionList主客观合并 func HandleEquityContractPermissionList(contractPermissionList []*company.ContractPermissionList) []*company.ContractPermissionList { if len(contractPermissionList) == 0 { return contractPermissionList } checkList := contractPermissionList[0].CheckList permissionList := contractPermissionList[0].Items newPermissionList := HandleEquityPermissionLookItem(checkList, permissionList) contractPermissionList[0].Items = newPermissionList return contractPermissionList } // HandleEquityPermissionLookItem 权益-权限展示的主客观合并处理 func HandleEquityPermissionLookItem(checkList []int, permissionList []*company.PermissionLookItem) (newPermissionList []*company.PermissionLookItem) { permissionLen := len(permissionList) if len(checkList) <= 0 || permissionLen <= 0 { return permissionList } // 若某个行业的主客观权限均被满足,则只留其中一个权限 // 1.取出每个行业对应的其中一个权限 industryName := []string{"医药", "消费", "科技", "智造"} namePermissionMap := make(map[string]*company.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 } } // 3.重新组成一个权限列表 mergeIndustryMap := make(map[string]int, 0) newPermissionList = make([]*company.PermissionLookItem, 0) for i := 0; i < permissionLen; i++ { item := permissionList[i] if utils.InArrayByStr(industryName, item.PermissionName) { // 只有主客观之一, permissionName取remark if countIndustryMap[item.PermissionName] == 1 { // CRM13.2 标准合同新增升级套餐 if item.IsUpgrade == 1 { item.PermissionName += "(升级)" newPermissionList = append(newPermissionList, item) } else { item.PermissionName = item.Remark newPermissionList = append(newPermissionList, item) } continue } // 主客观都有 if countIndustryMap[item.PermissionName] > 1 && mergeIndustryMap[item.PermissionName] == 0 { mergeIndustryMap[item.PermissionName] += 1 // CRM13.2 标准合同新增升级套餐 if item.IsUpgrade == 1 { item.PermissionName += "(升级)" } newPermissionList = append(newPermissionList, item) } } else { newPermissionList = append(newPermissionList, item) } } return } // handleRaiContractModifyContentByServices 权益合同-服务内容变更内容 func handleRaiContractModifyContentByServices(originService []*contract.ContractServiceAndDetail, newService []*contract.ContractServiceAndDetail) (tips string) { if originService == nil || newService == nil { return } oldArr := make([]string, 0) newArr := make([]string, 0) oldStr := "无" newStr := "无" o := EquityMergeSubjectAndObject(originService) n := EquityMergeSubjectAndObject(newService) for i := range o { oldArr = append(oldArr, o[i].Title) } if len(oldArr) > 0 { oldStr = strings.Join(oldArr, ",") } for i := range n { newArr = append(newArr, n[i].Title) } if len(newArr) > 0 { newStr = strings.Join(newArr, ",") } tips = fmt.Sprint("原服务内容:", oldStr, "现服务内容:", newStr) return } // 获取权益近一年是否有新签合同 func GetCompanyContractCountRaiByLastYear(companyId int, startDate string) (total int, err error) { firstContractRai, err := company.GetFirstContractRai(companyId) if err != nil && err.Error() != utils.ErrNoRow() { return } //没有合同这第一份合同就属于新签合同 if firstContractRai == nil { err = nil total = 1 return } //判断是否是在一年以内 startDateTime, _ := time.Parse(utils.FormatDate, startDate) startDateTime = startDateTime.AddDate(-1, 0, 0) startDateTimeFirst, _ := time.Parse(utils.FormatDate, firstContractRai.StartDate) if startDateTime.Before(startDateTimeFirst) { total = 1 } return } func initCRM15_5() { var condition string var pars []interface{} condition = " AND rai_contract_type = '新签合同' AND product_id = 2 " companyContractList, e := company.GetCompanyContractList(condition, pars) if e != nil && e.Error() != utils.ErrNoRow() { fmt.Println(e) return } var CompanyContractIdS []int for k, v := range companyContractList { fmt.Println(k) firstContractRai, err := company.GetFirstContractRai(v.CompanyId) if err != nil { fmt.Println(err) continue } if firstContractRai.CompanyContractId == v.CompanyContractId { continue } //判断是否是在一年以内 startDateTime, _ := time.Parse(utils.FormatDate, v.StartDate) startDateTime = startDateTime.AddDate(-1, 0, 0) startDateTimeFirst, _ := time.Parse(utils.FormatDate, firstContractRai.StartDate) if !startDateTime.Before(startDateTimeFirst) { CompanyContractIdS = append(CompanyContractIdS, v.CompanyContractId) } } fmt.Println("companyContractIds", len(CompanyContractIdS)) fmt.Println("companyContractIds", (CompanyContractIdS)) // //fmt.Println(strings.Join(companyContractIds, ",")) //err := company.UpdateCompanyContractRaiContractTypeInit(strings.Join(companyContractIds, ",")) //fmt.Println(err) return }