employee.go 12.5 KB
package service

import (
	"fmt"
	"github.com/linmadan/egglib-go/core/application"
	"github.com/linmadan/egglib-go/utils/tool_funs"
	"github.com/shopspring/decimal"
	"gitlab.fjmaimaimai.com/linmadan/mmm-worth/pkg/application/employee/command"
	"gitlab.fjmaimaimai.com/linmadan/mmm-worth/pkg/application/employee/query"
	"gitlab.fjmaimaimai.com/linmadan/mmm-worth/pkg/application/factory"
	"gitlab.fjmaimaimai.com/linmadan/mmm-worth/pkg/domain"
	"gitlab.fjmaimaimai.com/linmadan/mmm-worth/pkg/infrastructure/dao"
	"time"
)

// 员工服务
type EmployeeService struct {
}

// 创建新员工
func (employeeService *EmployeeService) CreateEmployee(createEmployeeCommand *command.CreateEmployeeCommand) (interface{}, error) {
	if err := createEmployeeCommand.ValidateCommand(); err != nil {
		return nil, application.ThrowError(application.ARG_ERROR, err.Error())
	}

	transactionContext, err := factory.CreateTransactionContext(nil)
	if err != nil {
		return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
	}
	if err := transactionContext.StartTransaction(); err != nil {
		return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
	}
	defer func() {
		transactionContext.RollbackTransaction()
	}()

	newEmployee := &domain.Employee{
		EmployeeInfo: &domain.EmployeeInfo{
			Uid:             createEmployeeCommand.Uid,
			EmployeeName:    createEmployeeCommand.EmployeeName,
			EmployeeAccount: createEmployeeCommand.EmployeeAccount,
		},
		SuMoney: 0,
		CreateTime: time.Now(),
	}
	var employeeRepository domain.EmployeeRepository

	// 创建员工工厂初始化
	if value, err := factory.CreateEmployeeRepository(map[string]interface{}{
		"transactionContext": transactionContext,
	}); err != nil {
		return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
	} else {
		employeeRepository = value
	}

	if employee, err := employeeRepository.Save(newEmployee); err != nil {
		return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
	} else {
		if err := transactionContext.CommitTransaction(); err != nil {
			return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
		}
		return employee, nil
	}
}

// 返回员工
func (employeeService *EmployeeService) GetEmployee(getEmployeeQuery *query.GetEmployeeQuery) (interface{}, error) {
	if err := getEmployeeQuery.ValidateQuery(); err != nil {
		return nil, application.ThrowError(application.ARG_ERROR, err.Error())
	}

	transactionContext, err := factory.CreateTransactionContext(nil)
	if err != nil {
		return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
	}
	if err := transactionContext.StartTransaction(); err != nil {
		return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
	}
	defer func() {
		transactionContext.RollbackTransaction()
	}()

	// 员工仓储初始化
	var employeeRepository domain.EmployeeRepository
	if value, err := factory.CreateEmployeeRepository(map[string]interface{}{
		"transactionContext": transactionContext,
	}); err != nil {
		return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
	} else {
		employeeRepository = value
	}

	// 员工DAO初始化
	var employeeDao *dao.EmployeeDao
	if value, err := factory.CreateEmployeeDao(map[string]interface{}{
		"transactionContext": transactionContext,
	}); err != nil {
		return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
	} else {
		employeeDao = value
	}

	var employeeSpecific map[string]interface{}

	// 默认查询时间
	transactionStartTime := time.Time{}
	transactionEndTime := time.Now()

	employee, err := employeeRepository.FindOne(map[string]interface{}{"uid": getEmployeeQuery.Uid})
	if err != nil {
		return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
	}
	if employee == nil {
		return nil, application.ThrowError(application.RES_NO_FIND_ERROR, fmt.Sprintf("%s", string(getEmployeeQuery.Uid)))
	} else {
		var contributions float64
		calculateResult, err := employeeDao.CalculateContributionsTransactionRecord(employee.EmployeeInfo.Uid, transactionStartTime, transactionEndTime)
		if err != nil {
			return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
		}
		if calculateResult == nil {
			return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
		}
		suMoney, _ := decimal.NewFromFloatWithExponent(employee.SuMoney, -2).Float64()
		if calculateResult["contributions"] != nil {
			contributions, _ = decimal.NewFromFloatWithExponent(calculateResult["contributions"].(float64), -2).Float64()
		}
		employeeSpecific = map[string]interface{} {
			"employeeId": employee.EmployeeId,
			"companyId": employee.CompanyId,
			"employeeInfo": map[string]interface{}{
				"uid": employee.EmployeeInfo.Uid,
				"employeeName": employee.EmployeeInfo.EmployeeName,
				"employeeAccount": employee.EmployeeInfo.EmployeeAccount,
				"employeeAvatarUrl": employee.EmployeeInfo.EmployeeAvatarUrl,
				"isPrincipal": employee.EmployeeInfo.IsPrincipal,
			},
			"suMoney": suMoney,
			"contributions": contributions,
			"status": employee.Status,
			"permissions": employee.Permissions,
			"createTime": employee.CreateTime.Local(),
		}

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

// 更新员工
func (employeeService *EmployeeService) UpdateEmployee(updateEmployeeCommand *command.UpdateEmployeeCommand) (interface{}, error) {
	if err := updateEmployeeCommand.ValidateCommand(); err != nil {
		return nil, application.ThrowError(application.ARG_ERROR, err.Error())
	}

	transactionContext, err := factory.CreateTransactionContext(nil)
	if err != nil {
		return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
	}
	if err := transactionContext.StartTransaction(); err != nil {
		return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
	}
	defer func() {
		transactionContext.RollbackTransaction()
	}()

	// 员工仓储初始化
	var employeeRepository domain.EmployeeRepository
	if value, err := factory.CreateEmployeeRepository(map[string]interface{}{
		"transactionContext": transactionContext,
	}); err != nil {
		return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
	} else {
		employeeRepository = value
	}

	employee, err := employeeRepository.FindOne(map[string]interface{}{"uid": updateEmployeeCommand.Uid})
	if err != nil {
		return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
	}
	if employee == nil {
		return nil, application.ThrowError(application.RES_NO_FIND_ERROR, fmt.Sprintf("%s", string(updateEmployeeCommand.Uid)))
	}
	updateEmployeeCommand.CreateTime = time.Now()
	if err := employee.Update(tool_funs.SimpleStructToMap(updateEmployeeCommand)); err != nil {
		return nil, application.ThrowError(application.BUSINESS_ERROR, err.Error())
	}
	if employee, err := employeeRepository.Save(employee); err != nil {
		return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
	} else {
		if err := transactionContext.CommitTransaction(); err != nil {
			return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
		}
		return employee, nil
	}
}

// 移除员工
func (employeeService *EmployeeService) RemoveEmployee(removeEmployeeCommand *command.RemoveEmployeeCommand) (interface{}, error) {
	if err := removeEmployeeCommand.ValidateCommand(); err != nil {
		return nil, application.ThrowError(application.ARG_ERROR, err.Error())
	}
	transactionContext, err := factory.CreateTransactionContext(nil)
	if err != nil {
		return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
	}
	if err := transactionContext.StartTransaction(); err != nil {
		return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
	}
	defer func() {
		transactionContext.RollbackTransaction()
	}()
	var employeeRepository domain.EmployeeRepository
	if value, err := factory.CreateEmployeeRepository(map[string]interface{}{
		"transactionContext": transactionContext,
	}); err != nil {
		return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
	} else {
		employeeRepository = value
	}
	employee, err := employeeRepository.FindOne(map[string]interface{}{"uid": removeEmployeeCommand.Uid})
	if err != nil {
		return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
	}
	if employee == nil {
		return nil, application.ThrowError(application.RES_NO_FIND_ERROR, fmt.Sprintf("%s", string(removeEmployeeCommand.Uid)))
	}
	if employee, err := employeeRepository.Remove(employee); err != nil {
		return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
	} else {
		if err := transactionContext.CommitTransaction(); err != nil {
			return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
		}
		return employee, nil
	}
}

// 返回员工列表
func (employeeService *EmployeeService) ListEmployee(listEmployeeQuery *query.ListEmployeeQuery) (interface{}, error) {
	if err := listEmployeeQuery.ValidateQuery(); err != nil {
		return nil, application.ThrowError(application.ARG_ERROR, err.Error())
	}

	transactionContext, err := factory.CreateTransactionContext(nil)
	if err != nil {
		return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
	}
	if err := transactionContext.StartTransaction(); err != nil {
		return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
	}
	defer func() {
		transactionContext.RollbackTransaction()
	}()

	// 员工仓储初始化
	var employeeRepository domain.EmployeeRepository
	if value, err := factory.CreateEmployeeRepository(map[string]interface{}{
		"transactionContext": transactionContext,
	}); err != nil {
		return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
	} else {
		employeeRepository = value
	}

	// 员工DAO初始化
	var employeeDao *dao.EmployeeDao
	if value, err := factory.CreateEmployeeDao(map[string]interface{}{
		"transactionContext": transactionContext,
	}); err != nil {
		return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
	} else {
		employeeDao = value
	}

	// 默认查询时间
	transactionStartTime := time.Time{}
	transactionEndTime := time.Now()

	var employeesSpecific []interface{}

	if count, employees, err := employeeRepository.Find(map[string]interface{}{
		"companyId": listEmployeeQuery.CompanyId,
		"employeeNameMatch": listEmployeeQuery.EmployeeNameMatch,
		"offset": listEmployeeQuery.Offset,
		"limit": listEmployeeQuery.Limit,
	}); err != nil {
		return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
	} else {
		for _ , employee := range employees {
			calculateResult, err := employeeDao.CalculateContributionsTransactionRecord(employee.EmployeeInfo.Uid, transactionStartTime, transactionEndTime)
			if err != nil {
				return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
			}
			if calculateResult == nil {
				return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
			}

			suMoney, _ := decimal.NewFromFloatWithExponent(employee.SuMoney, -2).Float64()
			var contributions float64
			if calculateResult["contributions"] != nil {
				contributions, _ = decimal.NewFromFloatWithExponent(calculateResult["contributions"].(float64), -2).Float64()
			}

			employeeSpecific := map[string]interface{}{
				"employeeId": employee.EmployeeId,
				"companyId": employee.CompanyId,
				"employeeInfo": map[string]interface{}{
					"uid": employee.EmployeeInfo.Uid,
					"employeeName": employee.EmployeeInfo.EmployeeName,
					"employeeAccount": employee.EmployeeInfo.EmployeeAccount,
					"employeeAvatarUrl": employee.EmployeeInfo.EmployeeAvatarUrl,
					"isPrincipal": employee.EmployeeInfo.IsPrincipal,
				},
				"suMoney": suMoney,
				"contributions": contributions,
				"status": employee.Status,
				"permissions": employee.Permissions,
				"createTime": employee.CreateTime.Local(),
			}
			employeesSpecific = append(employeesSpecific, employeeSpecific)
		}

		if err := transactionContext.CommitTransaction(); err != nil {
			return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
		}
		if len(employeesSpecific) == 0 {
			employeesSpecific = []interface{}{}
		}
		return map[string]interface{}{
			"count":     count,
			"employees": employeesSpecific,
		}, nil
	}
}

func NewEmployeeService(options map[string]interface{}) *EmployeeService {
	newEmployeeService := &EmployeeService{}
	return newEmployeeService
}