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
}
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{"权益"}
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
}
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
}