project_service.go 13.9 KB
package service

import (
	"fmt"
	"github.com/linmadan/egglib-go/core/application"
	"github.com/linmadan/egglib-go/utils/tool_funs"
	"gitlab.fjmaimaimai.com/allied-creation/performance/pkg/application/evaluation_project/adapter"
	"gitlab.fjmaimaimai.com/allied-creation/performance/pkg/application/evaluation_project/command"
	"gitlab.fjmaimaimai.com/allied-creation/performance/pkg/application/factory"
	"gitlab.fjmaimaimai.com/allied-creation/performance/pkg/domain"
	"strconv"
)

type EvaluationProjectService struct {
}

func NewEvaluationProjectService() *EvaluationProjectService {
	newRoleService := &EvaluationProjectService{}
	return newRoleService
}

// Create 创建
func (rs *EvaluationProjectService) Create(in *command.CreateProjectCommand) (interface{}, error) {
	transactionContext, err := factory.ValidateStartTransaction(in)
	if err != nil {
		return nil, err
	}
	defer func() {
		transactionContext.RollbackTransaction()
	}()
	projectRepository := factory.CreateEvaluationProjectRepository(map[string]interface{}{"transactionContext": transactionContext})

	// 检测名称重复
	count, err := projectRepository.Count(map[string]interface{}{"name": in.Name, "cycleId": in.CycleId, "companyId": in.CompanyId})
	if err != nil {
		return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
	}
	if count > 0 {
		return nil, application.ThrowError(application.BUSINESS_ERROR, "名称已存在")
	}

	newProject := &domain.EvaluationProject{
		Id:        0,
		Name:      in.Name,
		Describe:  in.Describe,
		CompanyId: in.CompanyId,
		CycleId:   in.CycleId,
		CreatorId: in.CreatorId,
		State:     domain.ProjectStateWaitConfig,
		HrBp:      in.HrBp,
		Pmp:       in.Pmp,
		PmpIds:    in.PmpIds,
	}
	project, err := projectRepository.Insert(newProject)
	if err != nil {
		return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
	}
	if err := transactionContext.CommitTransaction(); err != nil {
		return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
	}
	return project, nil

}

func (rs *EvaluationProjectService) Update(in *command.UpdateProjectCommand) (interface{}, error) {
	transactionContext, err := factory.ValidateStartTransaction(in)
	if err != nil {
		return nil, err
	}
	defer func() {
		transactionContext.RollbackTransaction()
	}()

	projectRepository := factory.CreateEvaluationProjectRepository(map[string]interface{}{"transactionContext": transactionContext})

	// 检测名称重复(排除自己)
	count, err := projectRepository.Count(map[string]interface{}{"name": in.Name, "cycleId": in.CycleId, "companyId": in.CompanyId, "notId": in.Id})
	if err != nil {
		return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
	}
	if count > 0 {
		return nil, application.ThrowError(application.BUSINESS_ERROR, "名称已存在")
	}

	project, err := projectRepository.FindOne(map[string]interface{}{"id": in.Id})
	if err != nil {
		return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
	}
	project.Name = in.Name
	project.Describe = in.Describe
	project.HrBp = in.HrBp
	project.Pmp = in.Pmp
	project.PmpIds = in.PmpIds

	project, err = projectRepository.Insert(project)
	if err != nil {
		return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
	}
	if err := transactionContext.CommitTransaction(); err != nil {
		return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
	}
	return project, nil
}

func (rs *EvaluationProjectService) UpdateTemplate(in *command.UpdateProjectTemplateCommand) (interface{}, error) {
	transactionContext, err := factory.ValidateStartTransaction(in)
	if err != nil {
		return nil, err
	}
	defer func() {
		transactionContext.RollbackTransaction()
	}()

	projectRepository := factory.CreateEvaluationProjectRepository(map[string]interface{}{"transactionContext": transactionContext})
	cycleTemplateRepository := factory.CreateEvaluationCycleTemplateRepository(map[string]interface{}{"transactionContext": transactionContext})

	_, projects, err := projectRepository.Find(map[string]interface{}{"companyId": in.CompanyId, "cycleId": in.CycleId}, "linkNodes")
	if err != nil {
		return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
	}

	// 周期内的所有项目,员工不能重复被评估
	rids := map[string]bool{}
	for i := range projects {
		// 排除当前项目
		if in.Id != projects[i].Id {
			ids := projects[i].Recipients
			for j := range ids {
				rids[ids[j]] = true
			}
		}
	}
	repeatNum := 0
	for i := range in.Recipients {
		id := in.Recipients[i]
		if _, ok := rids[id]; ok {
			repeatNum++
		}
	}
	if repeatNum > 0 {
		return nil, application.ThrowError(application.BUSINESS_ERROR, fmt.Sprintf("有%d人已经在本周期其他项目内,需要将他们移除", repeatNum))
	}

	project, err := projectRepository.FindOne(map[string]interface{}{"id": in.Id})
	if err != nil {
		return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
	}
	cycleTemplate, err := cycleTemplateRepository.FindOne(map[string]interface{}{"id": in.TemplateId, "includeDeleted": true})
	if err != nil {
		return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
	}

	project.Recipients = in.Recipients
	project.Template = cycleTemplate.Template

	project, err = projectRepository.Insert(project)
	if err != nil {
		return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
	}
	if err := transactionContext.CommitTransaction(); err != nil {
		return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
	}
	return project, nil
}

func (rs *EvaluationProjectService) UpdateTemplateNode(in *command.UpdateProjectTemplateNodeCommand) (interface{}, error) {
	transactionContext, err := factory.ValidateStartTransaction(in)
	if err != nil {
		return nil, err
	}
	defer func() {
		transactionContext.RollbackTransaction()
	}()

	projectRepository := factory.CreateEvaluationProjectRepository(map[string]interface{}{"transactionContext": transactionContext})

	project, err := projectRepository.FindOne(map[string]interface{}{"id": in.Id})
	if err != nil {
		return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
	}

	// FIXME 启动时,需要激活定时任务
	if in.Activate == 1 {
		project.State = domain.ProjectStateEnable
	}
	for i := range in.LinkNodes {
		project.Template.LinkNodes[i].TimeStart = in.LinkNodes[i].TimeStart
		project.Template.LinkNodes[i].TimeEnd = in.LinkNodes[i].TimeEnd
		project.Template.LinkNodes[i].KpiCycle = in.LinkNodes[i].KpiCycle
	}

	project, err = projectRepository.Insert(project)
	if err != nil {
		return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
	}
	if err := transactionContext.CommitTransaction(); err != nil {
		return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
	}
	return project, nil
}

func (rs *EvaluationProjectService) Get(in *command.GetProjectCommand) (interface{}, error) {
	transactionContext, err := factory.ValidateStartTransaction(in)
	if err != nil {
		return nil, err
	}
	defer func() {
		transactionContext.RollbackTransaction()
	}()
	projectRepository := factory.CreateEvaluationProjectRepository(map[string]interface{}{"transactionContext": transactionContext})
	project, err := projectRepository.FindOne(map[string]interface{}{"id": in.Id})
	if err != nil {
		return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
	}

	projectAdapter := &adapter.EvaluationProjectAdapter{}
	projectAdapter.EvaluationProject = project

	userRepository := factory.CreateUserRepository(map[string]interface{}{"transactionContext": transactionContext})
	if len(project.PmpIds) > 0 {
		_, users, _ := userRepository.Find(map[string]interface{}{"ids": project.PmpIds, "limit": len(project.PmpIds)})
		projectAdapter.TransformPmpAdapter(users)
	}

	if len(project.Recipients) > 0 {
		_, users, _ := userRepository.Find(map[string]interface{}{"ids": project.Recipients, "limit": len(project.Recipients)})
		projectAdapter.TransformRecipientAdapter(users)
	}

	if err := transactionContext.CommitTransaction(); err != nil {
		return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
	}
	return projectAdapter, nil
}

func (rs *EvaluationProjectService) Remove(in *command.DeleteProjectCommand) (interface{}, error) {
	transactionContext, err := factory.ValidateStartTransaction(in)
	if err != nil {
		return nil, err
	}
	defer func() {
		transactionContext.RollbackTransaction()
	}()

	projectRepository := factory.CreateEvaluationProjectRepository(map[string]interface{}{"transactionContext": transactionContext})

	project, err := projectRepository.FindOne(map[string]interface{}{"id": in.Id})
	if err != nil {
		return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
	}
	if _, err := projectRepository.Remove(project); err != nil {
		return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
	}

	if err := transactionContext.CommitTransaction(); err != nil {
		return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
	}
	return project, nil
}

func (rs *EvaluationProjectService) List(in *command.QueryProjectCommand) (interface{}, error) {
	transactionContext, err := factory.StartTransaction()
	if err != nil {
		return nil, err
	}
	defer func() {
		transactionContext.RollbackTransaction()
	}()

	projectRepository := factory.CreateEvaluationProjectRepository(map[string]interface{}{"transactionContext": transactionContext})
	total, projects, err := projectRepository.Find(tool_funs.SimpleStructToMap(in), "linkNodes")
	if err != nil {
		return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
	}
	pmpUsers := make([]*domain.User, 0)
	pmpUserIds := make([]int64, 0)
	for i := range projects {
		project := projects[i]
		for j := range project.PmpIds {
			userId, _ := strconv.ParseInt(project.PmpIds[j], 10, 64)
			pmpUserIds = append(pmpUserIds, userId)
		}
	}
	if len(pmpUserIds) > 0 {
		userRepository := factory.CreateUserRepository(map[string]interface{}{"transactionContext": transactionContext})
		_, users, _ := userRepository.Find(map[string]interface{}{"ids": pmpUserIds, "limit": len(pmpUserIds)})
		pmpUsers = users
	}
	projectAdapters := adapter.TransformProjectListAdapter(projects, pmpUsers)
	return tool_funs.SimpleWrapGridMap(total, projectAdapters), nil
}

func (rs *EvaluationProjectService) State(in *command.StateProjectCommand) (interface{}, error) {
	transactionContext, err := factory.ValidateStartTransaction(in)
	if err != nil {
		return nil, err
	}
	defer func() {
		transactionContext.RollbackTransaction()
	}()

	projectRepository := factory.CreateEvaluationProjectRepository(map[string]interface{}{"transactionContext": transactionContext})

	project, err := projectRepository.FindOne(map[string]interface{}{"id": in.Id})
	if err != nil {
		return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
	}

	project.State = in.State
	project, err = projectRepository.Insert(project)
	if err != nil {
		return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
	}
	if err := transactionContext.CommitTransaction(); err != nil {
		return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
	}
	return project, nil
}

func (rs *EvaluationProjectService) Copy(in *command.CopyProjectCommand) (interface{}, error) {
	transactionContext, err := factory.ValidateStartTransaction(in)
	if err != nil {
		return nil, err
	}
	defer func() {
		transactionContext.RollbackTransaction()
	}()
	projectRepository := factory.CreateEvaluationProjectRepository(map[string]interface{}{"transactionContext": transactionContext})
	project, err := projectRepository.FindOne(map[string]interface{}{"id": in.Id})
	if err != nil {
		return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
	}
	// ID重置
	project.Id = 0
	// 如果拷贝已经启用的模板,默认先设置为待启用
	if project.State == domain.ProjectStateEnable {
		project.State = domain.ProjectStateWaitActive
	}
	project, err = projectRepository.Insert(project)
	if err != nil {
		return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
	}
	if err := transactionContext.CommitTransaction(); err != nil {
		return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
	}
	return project, nil
}

func (rs *EvaluationProjectService) StatisticCycleUser(in *command.StatisticCycleProjectUserCommand) (interface{}, error) {
	transactionContext, err := factory.ValidateStartTransaction(in)
	if err != nil {
		return nil, err
	}
	defer func() {
		transactionContext.RollbackTransaction()
	}()
	projectRepository := factory.CreateEvaluationProjectRepository(map[string]interface{}{"transactionContext": transactionContext})
	_, projects, err := projectRepository.Find(tool_funs.SimpleStructToMap(in), "linkNodes")
	if err != nil {
		return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
	}

	userIds := make([]int64, 0)
	userIdMap := map[int64]int64{}
	for i := range projects {
		project := projects[i]
		for j := range project.Recipients {
			userId, _ := strconv.ParseInt(project.Recipients[j], 10, 64)
			userIdMap[userId] = userId
		}
	}
	for _, v := range userIdMap {
		userIds = append(userIds, v)
	}

	userTotal := 0
	departmentTotal := 0
	if len(userIds) > 0 {
		userRepository := factory.CreateUserRepository(map[string]interface{}{"transactionContext": transactionContext})
		_, users, _ := userRepository.Find(map[string]interface{}{"ids": userIds, "limit": len(userIds)})
		departmentIdMap := map[int]int{}
		for i := range users {
			for _, v := range users[i].DepartmentId {
				departmentIdMap[v] = v
			}
		}
		userTotal = len(users)
		departmentTotal = len(departmentIdMap)
	}

	if err := transactionContext.CommitTransaction(); err != nil {
		return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
	}
	return map[string]interface{}{"userTotal": userTotal, "departmentTotal": departmentTotal}, nil
}