package cygx

import (
	"encoding/json"
	"fmt"
	"github.com/rdlucklib/rdluck_tools/paging"
	"github.com/tealeg/xlsx"
	"hongze/hz_crm_api/controllers"
	"hongze/hz_crm_api/models"
	"hongze/hz_crm_api/models/company"
	"hongze/hz_crm_api/models/contract"
	"hongze/hz_crm_api/models/cygx"
	"hongze/hz_crm_api/models/system"
	cygxService "hongze/hz_crm_api/services/cygx"
	"hongze/hz_crm_api/utils"
	"math"
	"os"
	"path/filepath"
	"strconv"
	"strings"
	"time"
)

// ContractAllocationController 权益合同派单
type ContractAllocationController struct {
	controllers.BaseAuthController
}

// getQueryParams 获取基础查询信息
func getQueryParams(condition string, pars []interface{}, sysUser *system.Admin, tableAlias string) (newCondition string, newPars []interface{}) {
	if sysUser.RoleTypeCode == utils.ROLE_TYPE_CODE_FICC_ADMIN {
		condition += " AND " + tableAlias + "product_id=?"
		pars = append(pars, 1)
	} else if sysUser.RoleTypeCode == utils.ROLE_TYPE_CODE_RAI_ADMIN {
		condition += " AND " + tableAlias + "product_id=?"
		pars = append(pars, 2)
	} else if sysUser.RoleTypeCode == utils.ROLE_TYPE_CODE_ADMIN || sysUser.RoleTypeCode == utils.ROLE_TYPE_CODE_FINANCE {
		//超级管理员账户，不做条件限制
	} else {
		//如果不是研究员，那么去找对应的 部门、小组、销售
		if sysUser.Authority == 0 {
			//普通用户
			condition += " AND " + tableAlias + "seller_id=?"
			pars = append(pars, sysUser.AdminId)
		} else if sysUser.Authority == 1 {
			//部门主管
			condition += " AND " + tableAlias + "department_id=?"
			pars = append(pars, sysUser.DepartmentId)
		} else if sysUser.Authority == 2 && sysUser.RoleTypeCode == utils.ROLE_TYPE_CODE_RAI_GROUP {
			//权益小组负责人
			condition += " AND " + tableAlias + "group_id=?"
			pars = append(pars, sysUser.GroupId)
		} else if sysUser.Authority == 2 && sysUser.RoleTypeCode == utils.ROLE_TYPE_CODE_FICC_GROUP {
			//ficc销售主管
			pid, err := company.GetParentIdFromGroup(sysUser.GroupId)
			if err != nil {
				fmt.Println(err.Error())
				return
			}
			var ids []*string
			if pid != nil && *pid != 0 {
				ids, err = company.GetGroupIdsByParentId(*pid)
				if err != nil {
					fmt.Println(err.Error())
				}
			} else {
				ids, err = company.GetGroupIdsByParentId(sysUser.GroupId)
				if err != nil {
					fmt.Println(err.Error())
				}
			}
			var idSlice []string
			var sid string
			for _, id := range ids {
				idSlice = append(idSlice, *id)
			}
			//加入父级groupId
			if *pid > 0 {
				idSlice = append(idSlice, strconv.Itoa(*pid))
			} else {
				idSlice = append(idSlice, strconv.Itoa(sysUser.GroupId))
			}
			sid = strings.Join(idSlice, ",")
			condition += " AND " + tableAlias + `group_id IN (` + sid + `) `
			fmt.Println("condition:", condition)
			//pars = append(pars, sysUser.GroupId)
		} else if sysUser.Authority == 4 {
			//ficc小组负责人
			condition += " AND " + tableAlias + "group_id=?"
			pars = append(pars, sysUser.GroupId)
		} else {
			//不知道什么类型的用户（后面新增的位置类型客户）
			condition += " AND " + tableAlias + "seller_id=?"
			pars = append(pars, sysUser.AdminId)
		}
	}
	newCondition = condition
	newPars = pars
	return
}

// @Title 合同列表
// @Description 合同列表接口
// @Param   PageSize   query   int  true       "每页数据条数"
// @Param   CurrentIndex   query   int  true       "当前页页码，从1开始"
// @Param   Keyword   query   string  true       "客户名称"
// @Param   AdminId   query   string  true       "销售id，多个用英文逗号隔开，空字符串为全部"
// @Param   StartDate   query   string  false       "开始日期"
// @Param   EndDate   query   string  false       "结束日期"
// @Param   ContractType   query   string  false       "合同类型，枚举值：“，`新签合同`，`续约合同`，`补充协议`"
// @Param   FormalType   query   string  false     "转正类型，枚举值：“，`标准`，`非标`"
// @Param   IsExport   query   bool  false       "是否导出excel，默认是false"
// @Param   ResearcherRealName   query   string  false       "研究员姓名"
// @Param   IsAllocation   query   int  false       "派点状态: -1-默认全部; 0-未派点; 1-已派点"
// @Success 200 {object}  cygx.CompanyContractListResp
// @router /allocation/company_contract_list [get]
func (this *ContractAllocationController) CompanyContractList() {
	br := new(models.BaseResponse).Init()
	defer func() {
		this.Data["json"] = br
		this.ServeJSON()
	}()

	sysUser := this.SysUser
	if sysUser == nil {
		br.Msg = "请登录"
		br.ErrMsg = "请登录，SysUser Is Empty"
		br.Ret = 408
		return
	}

	pageSize, _ := this.GetInt("PageSize")
	currentIndex, _ := this.GetInt("CurrentIndex")
	adminId := this.GetString("AdminId")
	formalType := this.GetString("FormalType")
	contractType := this.GetString("ContractType")
	keyword := this.GetString("Keyword")
	startDate := this.GetString("StartDate")
	endDate := this.GetString("EndDate")
	researcherRealName := this.GetString("ResearcherRealName")
	isAllocation, _ := this.GetInt("IsAllocation", -1) // CRM 13.9
	if startDate == "" {
		startDate = "2015-01-01"
	}

	var startSize int
	if pageSize <= 0 {
		pageSize = utils.PageSize20
	}
	if currentIndex <= 0 {
		currentIndex = 1
	}
	startSize = utils.StartIndex(currentIndex, pageSize)
	//是否导出报表
	isExport, _ := this.GetBool("IsExport")
	if isExport {
		pageSize = 10000
		currentIndex = 1
	}

	var condition string
	var pars []interface{}

	if endDate != "" {
		condition += ` AND a.start_date >= ? AND a.start_date <= ? `
		pars = append(pars, startDate+" 00:00:01", endDate+" 23:59:59")
	}

	//条件
	if adminId != "" {
		condition += ` AND c.seller_id in  (` + adminId + `) `
		//pars = append(pars, adminId)
	}

	//权益申请销售只能看到自己名下的客户的申请
	companyIds, err := cygxService.GetAdminLookUserCompanyIdsBySelf(sysUser)
	if err != nil {
		br.Msg = "获取失败"
		br.ErrMsg = "获取失败，GetAdminLookUserCompanyIds Err:" + err.Error()
		return
	}
	lencompanyIds := len(companyIds)
	if lencompanyIds > 0 {
		condition += ` AND c.company_id IN (` + utils.GetOrmInReplace(lencompanyIds) + `)`
		pars = append(pars, companyIds)
	}

	//关键字搜索
	if keyword != "" {
		condition += ` and b.company_name like "%` + keyword + `%" `
	}

	//是否派点
	if isAllocation != -1 {
		condition += ` AND a.is_allocation = ? `
		pars = append(pars, isAllocation)
	}

	// 标准非标查询
	switch formalType {
	case "标准":
		condition += ` AND a.source = ? `
		pars = append(pars, "系统合同")
	case "非标":
		condition += ` AND a.source = ? `
		pars = append(pars, "上传附件")
	}

	if contractType != "" {
		condition += ` AND a.contract_type = ? `
		pars = append(pars, contractType)
	}

	//默认只查询权益 2023-06-01 之后的合同
	condition += ` AND c.product_id = ?  AND a.start_date > ? `
	pars = append(pars, 2, "2023-05-31")

	mapMoneyPoint := make(map[int]float64)
	//研究员姓名查询
	if researcherRealName != "" {
		var conditionAllocation string
		var parsAllocation []interface{}

		conditionAllocation = " AND  real_name = ? AND money != 0 "
		parsAllocation = append(parsAllocation, researcherRealName)
		allocationCompanyContractList, err := cygx.GetCygxAllocationCompanyContractList(conditionAllocation, parsAllocation)
		if err != nil {
			br.Msg = "获取失败"
			br.ErrMsg = "获取失败，GetCygxAllocationCompanyContractListErr:" + err.Error()
			return
		}
		var companyContractIds []int
		for _, v := range allocationCompanyContractList {
			companyContractIds = append(companyContractIds, v.CompanyContractId)
			mapMoneyPoint[v.CompanyContractId] = v.Money
		}
		lenCon := len(companyContractIds)
		if lenCon == 0 {
			condition += ` AND a.company_contract_id = 0 `
		} else {
			condition += ` AND a.company_contract_id IN   (` + utils.GetOrmInReplace(lenCon) + `)`
			pars = append(pars, companyContractIds)
		}
	}

	var list []*cygx.CompanyContractResp

	total, err := cygx.GetCompanyContractCountJoinCompany(condition, pars)
	if err != nil && err.Error() != utils.ErrNoRow() {
		br.Msg = "获取失败"
		br.ErrMsg = "获取失败，Err:" + err.Error()
		return
	}
	//列表页数据
	list, err = cygx.GetCompanyContractListJoinCompany(condition, pars, startSize, pageSize)
	if err != nil {
		br.Msg = "获取失败"
		br.ErrMsg = "获取失败，Err:" + err.Error()
		return
	}
	//mapCompamy := make(map[int]string)
	listLen := len(list)
	if listLen == 0 {
		list = make([]*cygx.CompanyContractResp, 0)
	} else {

		var contractCodes []string
		var companyContractIds []int
		for _, v := range list {
			switch v.Source {
			case "系统合同":
				v.FormalType = "标准"
			case "上传附件":
				v.FormalType = "非标"
			}
			contractCodes = append(contractCodes, v.ContractCode)
			companyContractIds = append(companyContractIds, v.CompanyContractId)
			//mapCompamy[v.CompanyId] = strconv.Itoa(v.CompanyContractId)
		}
		lencontractCodes := len(contractCodes)
		if lencontractCodes > 0 {
			//获取标准合同的ID，这里上面的查询已经关联了三张表，拆分吧。。。
			condition = ""
			joinStr := ""
			pars = make([]interface{}, 0)
			condition = " AND  a.contract_code  IN (" + utils.GetOrmInReplace(lencontractCodes) + ") "
			pars = append(pars, contractCodes)
			listContract, err := contract.GetContractList(condition, joinStr, pars, 0, lencontractCodes)
			if err != nil {
				br.Msg = "获取合同列表失败！"
				br.ErrMsg = "获取合同列表失败，Err:" + err.Error()
				return
			}

			mapContractCode := make(map[string]int)
			for _, v := range listContract {
				mapContractCode[v.ContractCode] = v.ContractId
			}

			mapIsGray, err := cygxService.GetMapIsGrayByCompanyContractIds(companyContractIds)
			if err != nil {
				br.Msg = "获取合同列表失败！"
				br.ErrMsg = "获取合同列表失败，GetMapIsGrayByCompanyContractIds Err:" + err.Error()
				return
			}

			//合并合同所对应的权限
			mappermissionName, err := cygxService.GetCompanyContractPermissionNameMapById(companyContractIds)
			if err != nil {
				br.Msg = "获取失败"
				br.ErrMsg = "获取失败，Err:" + err.Error()
				return
			}

			for _, v := range list {
				v.ContractId = mapContractCode[v.ContractCode]
				v.MoneyPoint = mapMoneyPoint[v.CompanyContractId]
				v.PermissionName = mappermissionName[v.CompanyContractId]
				v.IsGray = mapIsGray[v.CompanyContractId]
				if v.ContractType == "打分派点" {
					quarter, _ := utils.GetQuarterStrStartDatesInRange(v.StartDate, v.EndDate)
					v.Quarter = strings.Replace(quarter, ",", "+", -1)
				}
			}
		}
	}

	page := paging.GetPaging(currentIndex, pageSize, total)
	resp := cygx.CompanyContractListResp{
		Paging: page,
		List:   list,
	}
	//导出excel
	if isExport {
		CompanyContractListExport(this, resp, br)
		return
	}
	br.Ret = 200
	br.Success = true
	br.Msg = "获取成功"
	br.Data = resp
}

// CompanyContractListExport 导出Excel
func CompanyContractListExport(this *ContractAllocationController, resp cygx.CompanyContractListResp, br *models.BaseResponse) {
	dir, err := os.Executable()
	exPath := filepath.Dir(dir)
	downLoadnFilePath := exPath + "/" + time.Now().Format(utils.FormatDateTimeUnSpace) + ".xlsx"
	xlsxFile := xlsx.NewFile()
	if err != nil {
		br.Msg = "生成文件失败"
		br.ErrMsg = "生成文件失败"
		return
	}
	style := xlsx.NewStyle()
	alignment := xlsx.Alignment{
		Horizontal: "center",
		Vertical:   "center",
		WrapText:   true,
	}

	style.Alignment = alignment
	style.ApplyAlignment = true

	sheel, err := xlsxFile.AddSheet("派点导出数据")
	if err != nil {
		br.Msg = "新增Sheet失败"
		br.ErrMsg = "新增Sheet失败,Err:" + err.Error()
		return
	}
	sheel.SetColWidth(0, 0, 30)
	sheel.SetColWidth(1, 1, 15)
	sheel.SetColWidth(2, 2, 15)
	sheel.SetColWidth(3, 3, 18)

	titleRow := sheel.AddRow()

	cellA := titleRow.AddCell()
	cellA.SetStyle(style)
	cellA.SetValue("合同编号")

	cellB := titleRow.AddCell()
	cellB.SetStyle(style)
	cellB.SetValue("转正类型")

	cellC := titleRow.AddCell()
	cellC.SetStyle(style)
	cellC.SetValue("合同类型")

	cellD := titleRow.AddCell()
	cellD.SetStyle(style)
	cellD.SetValue("公司名称")

	cellE := titleRow.AddCell()
	cellE.SetStyle(style)
	cellE.SetValue("所属销售")

	cellF := titleRow.AddCell()
	cellF.SetStyle(style)
	cellF.SetValue("合同金额")

	cellG := titleRow.AddCell()
	cellG.SetStyle(style)
	cellG.SetValue("合同期限")

	cellH := titleRow.AddCell()
	cellH.SetStyle(style)
	cellH.SetValue("签约套餐")

	cellI := titleRow.AddCell()
	cellI.SetStyle(style)
	cellI.SetValue("状态")

	for _, v := range resp.List {
		dataRow := sheel.AddRow()
		dataRow.SetHeight(20)

		cellA := dataRow.AddCell()
		cellA.SetStyle(style)
		cellA.SetValue(v.ContractCode)

		cellB := dataRow.AddCell()
		cellB.SetStyle(style)
		cellB.SetValue(v.FormalType)

		cellC := dataRow.AddCell()
		cellC.SetStyle(style)
		cellC.SetValue(v.ContractType)

		cellD := dataRow.AddCell()
		cellD.SetStyle(style)
		cellD.SetValue(v.CompanyName)

		cellE := dataRow.AddCell()
		cellE.SetStyle(style)
		cellE.SetValue(v.SellerName)

		cellF := dataRow.AddCell()
		cellF.SetStyle(style)
		cellF.SetValue(v.Money)

		cellG := dataRow.AddCell()
		cellG.SetStyle(style)
		cellG.SetValue(fmt.Sprint(v.StartDate, " ~  ", v.EndDate))

		cellH := dataRow.AddCell()
		cellH.SetStyle(style)
		cellH.SetValue(v.PermissionName)

		cellI := dataRow.AddCell()
		cellI.SetStyle(style)
		if v.IsAllocation == 1 {
			cellI.SetValue("已派点")
		} else {
			cellI.SetValue("未派点")
		}
	}
	err = xlsxFile.Save(downLoadnFilePath)
	if err != nil {
		br.Msg = "保存文件失败"
		br.ErrMsg = "保存文件失败"
		return
	}
	randStr := time.Now().Format(utils.FormatDateTimeUnSpace)
	downloadFileName := "派点导出数据_" + randStr + ".xlsx"
	this.Ctx.Output.Download(downLoadnFilePath, downloadFileName)
	defer func() {
		os.Remove(downLoadnFilePath)
	}()
	br.Ret = 200
	br.Success = true
	br.Msg = "导出成功"
}

// @Title  详情
// @Description 获取详情接口
// @Param   CompanyContractId   query   int  true       "ID"
// @Param   ShowDetail   query   bool  false      "是否是派点详情展示"
// @Success Ret=200 {object} cygx.CygxAllocationCompanyContractDetailResp
// @router /allocation/detail [get]
func (this *ContractAllocationController) CompanyContracDetail() {
	br := new(models.BaseResponse).Init()
	defer func() {
		this.Data["json"] = br
		this.ServeJSON()
	}()
	AdminUser := this.SysUser
	if AdminUser == nil {
		br.Msg = "请登录"
		br.ErrMsg = "请登录，用户信息为空"
		br.Ret = 408
		return
	}
	resp := new(cygx.CygxAllocationCompanyContractDetailResp)
	companyContractId, _ := this.GetInt("CompanyContractId")
	if companyContractId < 1 {
		br.Msg = "请输入详情ID"
		return
	}
	showDetail, _ := this.GetBool("ShowDetail", false)
	contractItem, err := company.GetCompanyContractById(companyContractId)
	if err != nil {
		br.Msg = "获取信息失败"
		br.ErrMsg = "获取合同信息失败,Err:" + err.Error()
		return
	}
	total, err := cygx.GetCygxAllocationCompanyContractCountByCompanyContractId(companyContractId)
	if err != nil {
		br.Msg = "获取信息失败"
		br.ErrMsg = "获取合同信息失败,GetCygxAllocationCompanyContractCountByCompanyContractId Err:" + err.Error()
		return
	}

	companyProduct, err := company.GetCompanyProductByCompanyIdAndProductId(contractItem.CompanyId, utils.COMPANY_PRODUCT_RAI_ID)
	if err != nil {
		br.Msg = "查询客户产品信息失败"
		br.ErrMsg = "查询客户产品信息失败,Err:" + err.Error()
		return
	}

	//判断客户是否是永续（X类试用客户）
	if companyProduct.Status == utils.COMPANY_STATUS_FOREVER {
		resp.IsXClass = true
	}

	//var contractPermissionList []*company.ContractPermissionList
	//expMap := map[int]string{0: "(3w)", 1: "(5w)", 2: "(10w)"} // 买方研选价格
	hasPermissions, e := company.GetCompanyContractPermissionByCompanyContractId(companyContractId)
	if e != nil {
		br.Msg = "获取失败"
		br.ErrMsg = "获取合同权限信息失败，Err:" + e.Error()
		return
	}
	hasMap := make(map[int]*company.CompanyContractPermission)
	var pointMoney float64
	for _, p := range hasPermissions {
		hasMap[p.ChartPermissionId] = p
		if p.ChartPermissionId == utils.YAN_XUAN_KOU_DIAN_BAO_ID {
			pointMoney = math.Round(0.2*p.Points*100) / 100 // 将给定数字舍入到最近的整数，处理精度问题
		}
	}

	raiPermissions, e := company.GetPermissionLookItemsExt("2", utils.COMPANY_PRODUCT_RAI_NAME)
	if e != nil {
		br.Msg = "获取失败"
		br.ErrMsg = "获取权益权限列表失败, Err: " + e.Error()
		return
	}
	mapPermissionNameHave := make(map[string]bool) // 判断合同是否存在某一行业权限种类
	var expensiveYx int
	for _, n := range raiPermissions {

		match := hasMap[n.ChartPermissionId]
		if match == nil {
			continue
		}
		//研选订阅、研选扣点包 映射成买方研选
		if n.PermissionName == utils.CHART_PERMISSION_NAME_MF_YANXUAN || n.PermissionName == utils.YAN_XUAN_KOU_DIAN_BAO_NAME {
			n.PermissionName = utils.CHART_PERMISSION_NAME_MAI_FANG_YANXUAN
		}
		mapPermissionNameHave[n.PermissionName] = true
		// 买方研选(3w/5w/10w)
		if n.PermissionName == utils.CHART_PERMISSION_NAME_MF_YANXUAN {
			expensiveYx = match.ExpensiveYx
			//n.PermissionName += expMap[match.ExpensiveYx]
			continue
		}
	}
	//fmt.Println(mapPermissionNameHave)
	resp.Money = contractItem.Money / 10000
	//有研选时，对研选套餐类型做文案处理
	respItemYx := new(cygx.AllocationPermissionListResp)        // 研选订阅
	respItemYxKouDian := new(cygx.AllocationPermissionListResp) //  研选扣点
	if mapPermissionNameHave[utils.CHART_PERMISSION_NAME_MF_YANXUAN] || mapPermissionNameHave[utils.YAN_XUAN_KOU_DIAN_BAO_NAME] {
		var moneyYx float64
		if mapPermissionNameHave[utils.CHART_PERMISSION_NAME_MF_YANXUAN] {
			if expensiveYx == 0 {
				moneyYx = 3
			} else if expensiveYx == 1 {
				moneyYx = 5
			} else if expensiveYx == 2 {
				moneyYx = 10
			}
			respItemYx.Proportion = 0
			respItemYx.Money = moneyYx
			respItemYx.ChartPermissionName = utils.CHART_PERMISSION_NAME_MF_YANXUAN
			respItemYx.ChartPermissionId = utils.CHART_PERMISSION_ID_YANXUAN

			//手动拼接研选订阅的数据类型
			listYxItem := new(cygx.AllocationRealNameListResp)
			listYxItem.RealName = utils.CHART_PERMISSION_NAME_MF_YANXUAN
			listYxItem.Money = moneyYx
			listYxItem.ChartPermissionId = utils.CHART_PERMISSION_ID_YANXUAN
			respItemYx.List = append(respItemYx.List, listYxItem)
		}

		if mapPermissionNameHave[utils.YAN_XUAN_KOU_DIAN_BAO_NAME] {
			respItemYxKouDian.Proportion = 0
			respItemYxKouDian.Money = pointMoney
			respItemYxKouDian.ChartPermissionName = utils.YAN_XUAN_KOU_DIAN_BAO_NAME
			respItemYxKouDian.ChartPermissionId = utils.YAN_XUAN_KOU_DIAN_BAO_ID

			listKouDianItem := new(cygx.AllocationRealNameListResp)
			listKouDianItem.RealName = utils.YAN_XUAN_KOU_DIAN_BAO_NAME
			listKouDianItem.Money = pointMoney
			listKouDianItem.ChartPermissionId = utils.YAN_XUAN_KOU_DIAN_BAO_ID
			respItemYxKouDian.List = append(respItemYxKouDian.List, listKouDianItem)
		}

		resp.TotalPointsContent = fmt.Sprint(resp.Money, "W，", "其中", moneyYx+pointMoney, "w默认归属买方研选，请对剩余", resp.Money-moneyYx-pointMoney, "w按照100%进行比值分配")
		if showDetail {
			resp.TotalPointsContent = fmt.Sprint(resp.Money, "W")
		}
		resp.Money = resp.Money - moneyYx

	} else {
		resp.TotalPointsContent = fmt.Sprint(resp.Money, "W")
	}
	sysUserList, err := cygx.GetAskEmailListPoint()
	if err != nil {
		br.Msg = "获取失败"
		br.ErrMsg = "获取失败,GetAskEmailList Err: " + err.Error()
		return
	}
	mapPermissionUser := make(map[string][]*cygx.AllocationRealNameListResp)
	listPermission, err := cygx.GetChartPermissionAll()
	if err != nil {
		br.Msg = "获取信息失败"
		br.ErrMsg = "获取品种信息失败,Err:" + err.Error()
		return
	}
	mapPermissionId := make(map[string]int)
	for _, v := range listPermission {
		mapPermissionId[v.PermissionName] = v.ChartPermissionId
	}
	var respList []*cygx.AllocationPermissionListResp
	if total == 0 {
		for _, v := range sysUserList {
			if !mapPermissionNameHave[v.ChartPermissionName] {
				continue
			}
			item := new(cygx.AllocationRealNameListResp)
			item.RealName = v.Name
			item.ChartPermissionId = mapPermissionId[v.ChartPermissionName]
			mapPermissionUser[v.ChartPermissionName] = append(mapPermissionUser[v.ChartPermissionName], item)
		}

		for k, v := range mapPermissionUser {
			respItem := new(cygx.AllocationPermissionListResp)
			respItem.ChartPermissionName = k
			respItem.ChartPermissionId = mapPermissionId[k]
			respItem.List = v
			respList = append(respList, respItem)
		}
		////研选订阅
		//if respItemYx.ChartPermissionName != "" {
		//	respList = append(respList, respItemYx)
		//}
		////研选扣点
		//if respItemYxKouDian.ChartPermissionName != "" {
		//	respList = append(respList, respItemYxKouDian)
		//}

	} else {
		listUser, err := cygx.GetCygxAllocationCompanyContractListById(companyContractId)
		if err != nil {
			br.Msg = "获取失败"
			br.ErrMsg = "获取失败,GetCygxAllocationCompanyContractListById Err: " + err.Error()
			return
		}
		for _, v := range listUser {
			if showDetail && v.Money == 0 {
				continue
			}
			item := new(cygx.AllocationRealNameListResp)
			item.RealName = v.RealName
			item.Money = v.Money
			item.Proportion = v.Proportion
			item.ChartPermissionId = mapPermissionId[v.ChartPermissionName]
			mapPermissionUser[v.ChartPermissionName] = append(mapPermissionUser[v.ChartPermissionName], item)
		}
		listPermissionContract, err := cygx.GetCygxAllocationCompanyContractPermissionListById(companyContractId)
		if err != nil {
			br.Msg = "获取失败"
			br.ErrMsg = "获取失败,GetCygxAllocationCompanyContractPermissionListById Err: " + err.Error()
			return
		}
		for _, v := range listPermissionContract {
			if showDetail && v.Money == 0 {
				continue
			}
			respItem := new(cygx.AllocationPermissionListResp)
			respItem.ChartPermissionName = v.ChartPermissionName
			respItem.ChartPermissionId = mapPermissionId[v.ChartPermissionName]
			respItem.Money = v.Money
			respItem.Proportion = v.Proportion
			respItem.List = mapPermissionUser[v.ChartPermissionName]
			respList = append(respList, respItem)
		}
	}
	//处理是否置灰
	mapIsGray, err := cygxService.GetMapIsGrayByCompanyContractIds([]int{companyContractId})
	if err != nil {
		br.Msg = "获取合同列表失败！"
		br.ErrMsg = "获取合同列表失败，GetMapIsGrayByCompanyContractIds Err:" + err.Error()
		return
	}

	permissionNameArr := []string{"医药", "消费", "科技", "智造", "策略", "固收", utils.CHART_PERMISSION_NAME_MAI_FANG_YANXUAN}
	for _, v := range permissionNameArr {
		for _, v2 := range respList {
			if v2.ChartPermissionName == v {
				resp.List = append(resp.List, v2)
			}
		}
	}
	resp.IsGray = mapIsGray[companyContractId]
	//resp.List = respList
	resp.CompanyContractId = companyContractId
	resp.AllocationType = contractItem.AllocationType
	br.Ret = 200
	br.Success = true
	br.Msg = "获取成功"
	br.Data = resp
}

// @Title 更新派点
// @Description 更新派点接口
// @Param	request	body cygx.AddProductInteriorReq true "type json string"
// @Success 200 {object} "保存成功"
// @router /allocation/update [post]
func (this *ContractAllocationController) CompanyContracUpdate() {
	br := new(models.BaseResponse).Init()
	defer func() {
		this.Data["json"] = br
		this.ServeJSON()
	}()
	sysUser := this.SysUser
	if sysUser == nil {
		br.Msg = "请登录"
		br.ErrMsg = "请登录，SysUser Is Empty"
		br.Ret = 408
		return
	}
	var req cygx.UpdateAllocationCompanyContractReq
	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
	if err != nil {
		br.Msg = "参数解析异常！"
		br.ErrMsg = "参数解析失败，Err:" + err.Error()
		return
	}
	companyContractId := req.CompanyContractId
	if companyContractId == 0 {
		br.Msg = "参数错误"
		br.ErrMsg = "参数错误，id不可为空"
		return
	}
	mapIsGray, err := cygxService.GetMapIsGrayByCompanyContractIds([]int{companyContractId})
	if err != nil {
		br.Msg = "获取合同列表失败！"
		br.ErrMsg = "获取合同列表失败，GetMapIsGrayByCompanyContractIds Err:" + err.Error()
		return
	}
	if mapIsGray[companyContractId] {
		br.Msg = "超过180天，无法修改！"
		br.ErrMsg = "超过180天，无法修改，companyContractId :" + strconv.Itoa(companyContractId)
		return
	}

	contractItem, err := company.GetCompanyContractById(companyContractId)
	if err != nil {
		br.Msg = "获取信息失败"
		br.ErrMsg = "获取合同信息失败,Err:" + err.Error()
		return
	}

	companyProduct, err := company.GetCompanyProductByCompanyIdAndProductId(contractItem.CompanyId, utils.COMPANY_PRODUCT_RAI_ID)
	if err != nil {
		br.Msg = "查询客户产品信息失败"
		br.ErrMsg = "查询客户产品信息失败,Err:" + err.Error()
		return
	}

	money := contractItem.Money / 10000 // 合同金额，万为单位
	var moneyAvg float64                // 行业所占合同的平均金额
	hasPermissions, e := company.GetCompanyContractPermissionByCompanyContractId(companyContractId)
	if e != nil {
		br.Msg = "获取失败"
		br.ErrMsg = "获取合同权限信息失败，Err:" + e.Error()
		return
	}

	hasMap := make(map[int]*company.CompanyContractPermission)
	for _, p := range hasPermissions {
		hasMap[p.ChartPermissionId] = p
	}

	raiPermissions, e := company.GetPermissionLookItemsExt("2", utils.COMPANY_PRODUCT_RAI_NAME)
	if e != nil {
		br.Msg = "获取失败"
		br.ErrMsg = "获取权益权限列表失败, Err: " + e.Error()
		return
	}
	mapPermissionNameHave := make(map[string]bool) // 判断合同是否存在某一行业权限种类
	for _, n := range raiPermissions {
		//只计算，医药、消费、科技、智造、策略、固收、买方研选的
		if n.PermissionName != utils.YI_YAO_NAME && n.PermissionName != utils.XIAO_FEI_NAME && n.PermissionName != utils.KE_JI_NAME && n.PermissionName != utils.ZHI_ZAO_NAME && n.PermissionName != utils.CE_LUE_NAME && n.PermissionName != utils.GU_SHOU_NAME && n.PermissionName != utils.CHART_PERMISSION_NAME_MAI_FANG_YANXUAN {
			continue
		}
		match := hasMap[n.ChartPermissionId]
		if match == nil {
			continue
		}

		// 买方研选(3w/5w/10W)
		//if n.PermissionName == utils.CHART_PERMISSION_NAME_MF_YANXUAN {
		//	if match.ExpensiveYx == 1 {
		//		money = money - 5
		//	} else if match.ExpensiveYx == 2 {
		//		money = money - 10
		//	} else {
		//		money = money - 3
		//	}
		//} else {
		//	mapPermissionNameHave[n.PermissionName] = true
		//}
		mapPermissionNameHave[n.PermissionName] = true
	}

	if len(mapPermissionNameHave) > 0 {
		moneyAvg = money / float64(len(mapPermissionNameHave))
	}

	list := req.List
	var items []*cygx.CygxAllocationCompanyContract
	var itemsPermission []*cygx.CygxAllocationCompanyContractPermission

	var proportionSum float64 // 校验前端传过来的占比使用
	for _, v := range list {
		itemPermission := new(cygx.CygxAllocationCompanyContractPermission)
		itemPermission.CompanyContractId = companyContractId
		itemPermission.AdminId = sysUser.AdminId
		itemPermission.AdminName = sysUser.RealName
		itemPermission.Proportion = v.Proportion
		itemPermission.Money = v.Money
		if v.ChartPermissionName != utils.YAN_XUAN_KOU_DIAN_BAO_NAME {
			itemPermission.MoneyAvg = moneyAvg
			if v.Money < moneyAvg/2 && companyProduct.Status == utils.COMPANY_STATUS_FOREVER { //永续客户不做这种限制
				br.Msg = "单行业占比值不得低于平均值的一半"
				br.ErrMsg = "单行业占比值不得低于平均值的一半,Err:" + fmt.Sprint(proportionSum)
				return
			}
		}
		itemPermission.ChartPermissionName = v.ChartPermissionName
		itemPermission.CreateTime = time.Now()
		itemPermission.ModifyTime = time.Now()
		itemsPermission = append(itemsPermission, itemPermission)
		var userProportionSum float64 // 校验前端传过来的占比使用

		for _, v2 := range v.List {
			if v2.Proportion < -20 && companyProduct.Status == utils.COMPANY_STATUS_FOREVER { //永续客户不做这种限制
				br.Msg = "研究员占比值不得小于总额的-20%"
				br.ErrMsg = "研究员占比值不得小于总额的20%,Err:" + fmt.Sprint(proportionSum)
				return
			}
			item := new(cygx.CygxAllocationCompanyContract)
			item.CompanyContractId = companyContractId
			item.AdminId = sysUser.AdminId
			item.AdminName = sysUser.RealName
			item.Proportion = v2.Proportion
			item.Money = v2.Money
			item.RealName = v2.RealName
			item.ChartPermissionName = v.ChartPermissionName
			item.CreateTime = time.Now()
			item.ModifyTime = time.Now()
			items = append(items, item)
			proportionSum += v2.Proportion
			userProportionSum += v2.Proportion
		}
		//先添加0.2%的精度校验
		if userProportionSum > (v.Proportion+0.2) || userProportionSum < (v.Proportion-0.2) {
			br.Msg = "单行业下的研究员比值之和不等于行业占比值"
			br.ErrMsg = "单行业下的研究员比值之和不等于行业占比值"
			return
		}
	}

	//先添加0.5%的精度校验
	if proportionSum > 100.5 || proportionSum < 99.5 {
		br.Msg = "行业总比值相加不等于100%"
		br.ErrMsg = "行业总比值相加不等于100%,Err:"
		return
	}

	err = cygx.AddAndUpdateCygxAllocationCompanyContract(items, itemsPermission, companyContractId)
	if err != nil {
		br.Msg = "操作失败"
		br.ErrMsg = "操作失败,AddAndUpdateCygxAllocationCompanyContract Err:" + err.Error()
		return
	}

	br.Ret = 200
	br.Success = true
	br.IsAddLog = true
	br.Msg = "操作成功"
}

// @Title 研究员派点统计
// @Description 研究员派点统计接口
// @Param   PageSize   query   int  true       "每页数据条数"
// @Param   CurrentIndex   query   int  true       "当前页页码，从1开始"
// @Param   Keyword   query   string  true       "客户名称"
// @Param   StartDate   query   string  false       "开始日期"
// @Param   EndDate   query   string  false       "结束日期"
// @Param   IsExport   query   bool  false       "是否导出excel，默认是false"
// @Success 200 {object}  cygx.CompanyContractListResp
// @router /allocation/statistics [get]
func (this *ContractAllocationController) CompanyContractStatistics() {
	br := new(models.BaseResponse).Init()
	defer func() {
		this.Data["json"] = br
		this.ServeJSON()
	}()

	sysUser := this.SysUser
	if sysUser == nil {
		br.Msg = "请登录"
		br.ErrMsg = "请登录，SysUser Is Empty"
		br.Ret = 408
		return
	}

	keyword := this.GetString("Keyword")
	startDate := this.GetString("StartDate")
	endDate := this.GetString("EndDate")
	if startDate == "" {
		startDate = "2015-01-01"
	}

	//是否导出报表
	isExport, _ := this.GetBool("IsExport")

	var condition string

	var pars []interface{}
	if endDate != "" {
		condition += ` AND a.start_date >= ? AND a.start_date <= ? `
		pars = append(pars, startDate+" 00:00:01", endDate+" 23:59:59")
	}
	//根据当前角色来获取查询条件
	//condition, pars = getQueryParams(condition, pars, sysUser, "c.")

	companyIds, err := cygxService.GetAdminLookUserCompanyIdsBySelf(sysUser)
	if err != nil {
		br.Msg = "获取失败"
		br.ErrMsg = "获取失败，GetAdminLookUserCompanyIds Err:" + err.Error()
		return
	}
	lencompanyIds := len(companyIds)
	if lencompanyIds > 0 {
		condition += ` AND c.company_id IN (` + utils.GetOrmInReplace(lencompanyIds) + `)`
		pars = append(pars, companyIds)
	}

	//关键字搜索
	if keyword != "" {
		condition += ` and b.company_name like "%` + keyword + `%" `
	}

	//默认只查询权益 2023-06-01 之后的合同
	condition += ` AND c.product_id = ?  AND a.start_date > ?   `
	pars = append(pars, 2, "2023-05-31")

	//列表页数据
	listContract, err := cygx.GetCompanyContractListJoinCompany(condition, pars, 0, 1000)
	if err != nil {
		br.Msg = "获取失败"
		br.ErrMsg = "获取失败，Err:" + err.Error()
		return
	}
	//return
	var companyContractIds []int
	companyContractIdBool := make(map[int]bool)
	for _, v := range listContract {
		companyContractIds = append(companyContractIds, v.CompanyContractId)
	}

	lenArr := len(companyContractIds)
	mapUserAllocation := make(map[string]float64) // 关联合同
	mapUserMoney := make(map[string]float64)      // 派点金额
	mapPermissionAllocation := make(map[string]float64)
	mapPermissionMoney := make(map[string]float64)
	mapPermissionMoneyAvg := make(map[string]float64)
	mapPermissionContract := make(map[string]float64) // 行业关联的合同数量
	mapPermissionContractKey := make(map[string]bool) // 行业关联的合同数量键值对

	//totalContract := lenArr //所有的关联合同
	var totalMoney float64 //所有的关联合同的金额 单位万
	if lenArr > 0 {
		var conditionAllocation string
		var parsAllocation []interface{}
		conditionAllocation = ` AND company_contract_id IN(` + utils.GetOrmInReplace(lenArr) + ` ) `
		parsAllocation = append(parsAllocation, companyContractIds)
		allocationCompanyContractList, err := cygx.GetCygxAllocationCompanyContractList(conditionAllocation, parsAllocation)
		if err != nil {
			br.Msg = "获取失败"
			br.ErrMsg = "获取失败，Err:" + err.Error()
			return
		}
		allocationCompanyContractPermissionList, err := cygx.GetCygxAllocationCompanyContractPermissionList(conditionAllocation, parsAllocation)
		if err != nil {
			br.Msg = "获取失败"
			br.ErrMsg = "获取失败，Err:" + err.Error()
			return
		}
		for _, v := range allocationCompanyContractList {

			//if v.Proportion != 0 && v.ChartPermissionName != utils.CHART_PERMISSION_NAME_MF_YANXUAN {
			mapUserAllocation[v.RealName] += 1
			mapUserMoney[v.RealName] += v.Money
			mapPermissionAllocation[v.ChartPermissionName] += 1
			mapPermissionMoney[v.ChartPermissionName] += v.Money
			totalMoney += v.Money
			companyContractIdBool[v.CompanyContractId] = true
			//统计单个行业所关的合同数量
			if !mapPermissionContractKey[fmt.Sprint("ChartPermissionName_", v.ChartPermissionName, "CompanyContractId_", v.CompanyContractId)] {
				mapPermissionContract[v.ChartPermissionName] += 1
				mapPermissionContractKey[fmt.Sprint("ChartPermissionName_", v.ChartPermissionName, "CompanyContractId_", v.CompanyContractId)] = true
			}
			//dd = decimal.NewFromFloat(v.Money).Add(dd)
			//}
		}
		for _, v := range allocationCompanyContractPermissionList {
			mapPermissionMoneyAvg[v.ChartPermissionName] += v.MoneyAvg
		}
	}

	sysUserList, err := cygx.GetAskEmailListPoint()
	if err != nil {
		br.Msg = "获取失败"
		br.ErrMsg = "获取失败,GetAskEmailList Err: " + err.Error()
		return
	}

	mapPermissionUser := make(map[string][]*cygx.AllocationRealNameStatisticsListResp) //行业分组 map

	for _, v := range sysUserList {
		item := new(cygx.AllocationRealNameStatisticsListResp)
		item.RealName = v.Name
		item.TotalRelatedContract = mapUserAllocation[v.Name]
		item.TotalDispatchPoint = utils.SubFloatToString(mapUserMoney[v.Name], 2)
		if item.TotalDispatchPoint == "" {
			item.TotalDispatchPoint = "0"
		}
		//组内占比
		if mapUserMoney[v.Name] == 0 {
			item.GroupProportion = ""
		} else {
			item.GroupProportion = utils.SubFloatToString(mapUserMoney[v.Name]/mapPermissionMoney[v.ChartPermissionName]*100, 2)
		}
		if item.GroupProportion == "" {
			item.GroupProportion = "0"
		}
		item.GroupProportion += "%"

		//部门占比
		if totalMoney == 0 {
			item.DepartmentProportion = ""
		} else {
			item.DepartmentProportion = utils.SubFloatToString(mapUserMoney[v.Name]/totalMoney*100, 2)
		}
		if item.DepartmentProportion == "" {
			item.DepartmentProportion = "0"
		}
		item.DepartmentProportion += "%"
		mapPermissionUser[v.ChartPermissionName] = append(mapPermissionUser[v.ChartPermissionName], item)
	}

	for k, v := range mapPermissionUser {
		lenUser := len(v)
		item := new(cygx.AllocationRealNameStatisticsListResp)
		item.RealName = "合计"
		item.TotalRelatedContract = mapPermissionContract[k]
		item.TotalDispatchPoint = fmt.Sprint(utils.SubFloatToString(mapPermissionMoney[k], 2), "/", utils.SubFloatToString(mapPermissionMoneyAvg[k], 2))
		item.GroupProportion = "100%"

		//部门占比
		if totalMoney == 0 {
			item.DepartmentProportion = ""
		} else {
			item.DepartmentProportion = utils.SubFloatToString(mapPermissionMoney[k]/totalMoney*100, 2)
		}
		if item.DepartmentProportion == "" {
			item.DepartmentProportion = "0"
		}
		item.DepartmentProportion += "%"
		mapPermissionUser[k] = append(mapPermissionUser[k], item)

		item = new(cygx.AllocationRealNameStatisticsListResp)
		item.RealName = "平均"
		item.TotalRelatedContract = utils.SubFloatToFloat(mapPermissionAllocation[k]/float64(lenUser), 2)
		item.TotalDispatchPoint = utils.SubFloatToString(mapPermissionMoney[k]/float64(lenUser), 2)

		//组内占比
		if mapPermissionMoney[k] == 0 {
			item.GroupProportion = ""
		} else {
			item.GroupProportion = utils.SubFloatToString(1/(float64(len(mapPermissionUser[k])-1))*100, 2)
		}
		if item.GroupProportion == "" {
			item.GroupProportion = "0"
		}
		item.GroupProportion += "%"

		// 部门占比
		if totalMoney == 0 {
			item.DepartmentProportion = ""
		} else {
			item.DepartmentProportion = utils.SubFloatToString(mapPermissionMoney[k]/totalMoney*100/float64(len(mapPermissionUser[k])-1), 2)
		}

		if item.DepartmentProportion == "" {
			item.DepartmentProportion = "0"
		}
		item.DepartmentProportion += "%"
		mapPermissionUser[k] = append(mapPermissionUser[k], item)
	}

	var list []*cygx.AllocationPermissionStatisticsListResp
	permissionNameArr := []string{"医药", "消费", "科技", "智造", "策略", "固收", "买方研选"}
	for _, v := range permissionNameArr {
		item := new(cygx.AllocationPermissionStatisticsListResp)
		item.ChartPermissionName = v
		item.List = mapPermissionUser[v]
		list = append(list, item)
	}

	resp := cygx.CygxAllocationCompanyContractDetailStatisticsResp{
		List: list,
	}
	resp.TotalContract = len(companyContractIdBool)
	resp.TotalMoney = utils.SubFloatToFloat(totalMoney, 2)
	//导出excel
	if isExport {
		CompanyContractStatisticsExport(this, resp, br)
		return
	}
	br.Ret = 200
	br.Success = true
	br.Msg = "获取成功"
	br.Data = resp
}

// CompanyContractStatisticsExport 导出Excel
func CompanyContractStatisticsExport(this *ContractAllocationController, resp cygx.CygxAllocationCompanyContractDetailStatisticsResp, br *models.BaseResponse) {
	dir, err := os.Executable()
	exPath := filepath.Dir(dir)
	downLoadnFilePath := exPath + "/" + time.Now().Format(utils.FormatDateTimeUnSpace) + ".xlsx"
	xlsxFile := xlsx.NewFile()
	if err != nil {
		br.Msg = "生成文件失败"
		br.ErrMsg = "生成文件失败"
		return
	}
	style := xlsx.NewStyle()
	alignment := xlsx.Alignment{
		Horizontal: "center",
		Vertical:   "center",
		WrapText:   true,
	}

	style.Alignment = alignment
	style.ApplyAlignment = true

	sheel, err := xlsxFile.AddSheet("研究员派点统计")
	if err != nil {
		br.Msg = "新增Sheet失败"
		br.ErrMsg = "新增Sheet失败,Err:" + err.Error()
		return
	}
	sheel.SetColWidth(0, 0, 30)
	sheel.SetColWidth(1, 1, 15)
	sheel.SetColWidth(2, 2, 15)
	sheel.SetColWidth(3, 3, 18)

	titleRow := sheel.AddRow()

	cellA := titleRow.AddCell()
	cellA.SetStyle(style)
	cellA.SetValue("组别")

	cellB := titleRow.AddCell()
	cellB.SetStyle(style)
	cellB.SetValue("研究员")

	cellC := titleRow.AddCell()
	cellC.SetStyle(style)
	cellC.SetValue("关联合同")

	cellD := titleRow.AddCell()
	cellD.SetStyle(style)
	cellD.SetValue("总派点")

	cellE := titleRow.AddCell()
	cellE.SetStyle(style)
	cellE.SetValue("组内占比")

	cellF := titleRow.AddCell()
	cellF.SetStyle(style)
	cellF.SetValue("部门占比")

	for _, v := range resp.List {
		for k2, v2 := range v.List {

			dataRow := sheel.AddRow()
			dataRow.SetHeight(20)

			cellA := dataRow.AddCell()
			cellA.SetStyle(style)
			cellA.SetValue(v.ChartPermissionName)
			if k2 < len(v.List)-1 {
				cellA.VMerge = 1
			}

			cellB := dataRow.AddCell()
			cellB.SetStyle(style)
			cellB.SetValue(v2.RealName)

			cellC := dataRow.AddCell()
			cellC.SetStyle(style)
			cellC.SetValue(v2.TotalRelatedContract)

			cellD := dataRow.AddCell()
			cellD.SetStyle(style)
			cellD.SetValue(v2.TotalDispatchPoint)

			cellE := dataRow.AddCell()
			cellE.SetStyle(style)
			cellE.SetValue(v2.GroupProportion)

			cellF := dataRow.AddCell()
			cellF.SetStyle(style)
			cellF.SetValue(v2.DepartmentProportion)
		}
	}

	titleRow = sheel.AddRow()
	cellA = titleRow.AddCell()
	cellA.HMerge = 1
	cellA.SetStyle(style)
	cellA.SetValue("部门合计")

	cellB = titleRow.AddCell()
	cellB.SetStyle(style)
	cellB.SetValue("")

	cellC = titleRow.AddCell()
	cellC.SetStyle(style)
	cellC.SetValue(resp.TotalContract)

	cellD = titleRow.AddCell()
	cellD.SetStyle(style)
	cellD.SetValue(resp.TotalMoney)

	cellE = titleRow.AddCell()
	cellE.SetStyle(style)
	cellE.SetValue("-")

	cellF = titleRow.AddCell()
	cellF.SetStyle(style)
	cellF.SetValue("100%")

	err = xlsxFile.Save(downLoadnFilePath)
	if err != nil {
		br.Msg = "保存文件失败"
		br.ErrMsg = "保存文件失败"
		return
	}
	randStr := time.Now().Format(utils.FormatDateTimeUnSpace)
	downloadFileName := "研究员派点统计_" + randStr + ".xlsx"
	this.Ctx.Output.Download(downLoadnFilePath, downloadFileName)
	defer func() {
		os.Remove(downLoadnFilePath)
	}()
	br.Ret = 200
	br.Success = true
	br.Msg = "导出成功"
}
