pg_employee_dao.go 11.5 KB
package dao

import (
	"fmt"
	"github.com/go-pg/pg"
	pgTransaction "github.com/linmadan/egglib-go/transaction/pg"
	"gitlab.fjmaimaimai.com/linmadan/mmm-worth/pkg/domain"
	"gitlab.fjmaimaimai.com/linmadan/mmm-worth/pkg/infrastructure/pg/models"
	"time"
)

type EmployeeDao struct {
	transactionContext *pgTransaction.TransactionContext
}

func (dao *EmployeeDao) BatchRemove(uids []int64) error {
	tx := dao.transactionContext.PgTx
	_, err := tx.QueryOne(
		pg.Scan(),
		"DELETE FROM employees WHERE uid IN (?)",
		pg.In(uids))
	return err
}

func (dao *EmployeeDao) BatchSetStatus(uids []int64, status int) error {
	tx := dao.transactionContext.PgTx
	_, err := tx.QueryOne(
		pg.Scan(),
		"UPDATE employees SET status=? WHERE uid IN (?)",
		status, pg.In(uids))
	return err
}

func (dao *EmployeeDao) ChangePrincipal(companyId int64, employeeAccount string) error {
	tx := dao.transactionContext.PgTx
	if _, err := tx.Query(
		pg.Scan(),
		"UPDATE employees SET is_principal=? WHERE company_id=?",
		false, companyId); err != nil {
		return err
	}
	if _, err := tx.QueryOne(
		pg.Scan(),
		"UPDATE employees SET is_principal=? WHERE company_id=? AND employee_account=?",
		true, companyId, employeeAccount); err != nil {
		return err
	}
	return nil
}

func (dao *EmployeeDao) TransferSuMoney(uid int64, suMoney float64) error {
	tx := dao.transactionContext.PgTx
	_, err := tx.QueryOne(
		pg.Scan(),
		"UPDATE employees SET su_money=su_money+? WHERE uid=?",
		suMoney, uid)
	return err
}

func (dao *EmployeeDao) CalculatePersonUnReadNotification(uid int64) (map[string]int, error) {
	var unReadSystemNotification int
	var unReadInteractionNotification int
	tx := dao.transactionContext.PgTx
	sentNotificationModel := new(models.SentNotification)
	if count, err := tx.Model(sentNotificationModel).Relation("Notification").
		Where(`sent_notification.receiver @> '{"uid":?}'`, uid).
		Where("notification.notification_type = ?", domain.NOTIFICATION_TYPE_SYSTEM).
		Where("sent_notification.is_read = ?", false).
		Count(); err != nil {
		return nil, err
	} else {
		unReadSystemNotification = count
	}
	if count, err := tx.Model(sentNotificationModel).Relation("Notification").
		Where(`sent_notification.receiver @> '{"uid":?}'`, uid).
		Where("notification.notification_type = ?", domain.NOTIFICATION_TYPE_INTERACTION).
		Where("sent_notification.is_read = ?", false).
		Count(); err != nil {
		return nil, err
	} else {
		unReadInteractionNotification = count
	}
	return map[string]int{
		"unReadSystemNotification":      unReadSystemNotification,
		"unReadInteractionNotification": unReadInteractionNotification,
	}, nil
}

func (dao *EmployeeDao) CalculatePersonSuMoney(uid int64) (map[string]interface{}, error) {
	var incomeSuMoney float64
	var incomeSuMoneyOfYesterday float64
	tx := dao.transactionContext.PgTx
	suMoneyTransactionRecordModel := new(models.SuMoneyTransactionRecord)
	yesterday := time.Now().AddDate(0, 0, -1)
	if err := tx.Model(suMoneyTransactionRecordModel).
		ColumnExpr("sum(su_money_transaction_record.su_money) AS income_su_money").
		Where(`su_money_transaction_record.employee @> '{"uid":?}'`, uid).
		Where(`su_money_transaction_record.record_type = ?`, 2).
		Where(`su_money_transaction_record.create_time > ?`, time.Date(yesterday.Year(), yesterday.Month(), yesterday.Day(), 0, 0, 0, 0, yesterday.Location())).
		Where(`su_money_transaction_record.create_time < ?`, time.Date(yesterday.Year(), yesterday.Month(), yesterday.Day(), 23, 59, 59, 0, yesterday.Location())).
		Select(&incomeSuMoneyOfYesterday); err != nil {
		return nil, err
	}
	if err := tx.Model(suMoneyTransactionRecordModel).
		ColumnExpr("sum(su_money_transaction_record.su_money) AS income_su_money").
		Where(`su_money_transaction_record.employee @> '{"uid":?}'`, uid).
		Where(`su_money_transaction_record.record_type = ?`, 2).
		Select(&incomeSuMoney); err != nil {
		return nil, err
	}
	return map[string]interface{}{
		"incomeSuMoney":            incomeSuMoney,
		"incomeSuMoneyOfYesterday": incomeSuMoneyOfYesterday,
	}, nil
}

// 系统已兑换素币、未兑换素币
func (dao *EmployeeDao) CalculateSystemSuMoney(companyId int64) (map[string] interface{}, error) {
	var systemUnExchangeSuMoney float64
	var systemExchangedSuMoney float64
	tx := dao.transactionContext.PgTx
	// 系统未兑换素币
	employeeModel := new(models.Employee)
	if err := tx.Model(employeeModel).
		ColumnExpr("sum(employee.su_money) AS system_unExchange_su_money").
		Where("employee.company_id = ?", companyId).
		Where("employee.status = ?", 1).
		Select(&systemUnExchangeSuMoney); err != nil {
		return nil, err
	}
	// 系统已兑换现金素币
	suMoneyTransactionRecordModel := new(models.SuMoneyTransactionRecord)
	if err := tx.Model(suMoneyTransactionRecordModel).Join("JOIN employees AS e ON e.uid = (su_money_transaction_record.employee->>'uid')::bigint").
		ColumnExpr("sum(su_money_transaction_record.su_money) AS system_changed_su_money").
		Where("e.company_id = ?", companyId).
		Where("e.status = ?", 1).
		Where(`su_money_transaction_record.record_type = ?`, 5).
		Select(&systemExchangedSuMoney); err != nil {
		return nil, err
	}
	return  map[string] interface{} {
		"systemUnExchangeSuMoney": systemUnExchangeSuMoney,
		"systemExchangedSuMoney": systemExchangedSuMoney,
	},nil
}

// 计算系统已兑换现金、未兑换现金
func (dao *EmployeeDao) CalculateSystemCash(companyId int64) (map[string] interface{}, error) {
	tx := dao.transactionContext.PgTx
	var (
		systemUnExchangeCash float64
		systemExchangedCash float64
	)
	// 系统未兑换现金
	cashPool := new(models.CashPool)
	if err := tx.Model(cashPool).
		Column("exchanged_cash").
		Where("cash_pool.company_id = ?", companyId).
		Order("id DESC").
		Limit(1).
		Select(&systemExchangedCash) ; err != nil {
		return nil, err
	}
	if err := tx.Model(cashPool).
		Column("un_exchange_cash").
		Where("cash_pool.company_id = ?", companyId).
		Order("id DESC").
		Limit(1).
		Select(&systemUnExchangeCash) ; err != nil {
		return nil, err
	}
	return map[string] interface{} {
		"systemUnExchangeCash": systemUnExchangeCash,
		"systemExchangedCash": systemExchangedCash,
	}, nil
}

// 个人素币事务统计
func (dao *EmployeeDao) CalculateSuMoneyTransactionRecord(uid int64, transactionStartTime time.Time, transactionEndTime time.Time) (map[string]interface{}, error) {
	var incomeSuMoney float64  // 收入的素币(2:任务奖励,3:增加)
	var expendSuMoney float64  // 消耗的素币(1:兑换物资,4:扣除, 5: 兑换现金)
	tx := dao.transactionContext.PgTx
	suMoneyTransactionRecordModel := new(models.SuMoneyTransactionRecord)
	if err := tx.Model(suMoneyTransactionRecordModel).
		ColumnExpr("sum(su_money_transaction_record.su_money) AS income_su_money").
		Where(`su_money_transaction_record.employee @> '{"uid":?}'`, uid).
		Where(`su_money_transaction_record.record_type IN (?)`, pg.In([]int{2, 3})).
		Where(`su_money_transaction_record.create_time > ?`, transactionStartTime).
		Where(`su_money_transaction_record.create_time < ?`, transactionEndTime).
		Select(&incomeSuMoney); err != nil {
		return nil, err
	}
	if err := tx.Model(suMoneyTransactionRecordModel).
		ColumnExpr("sum(su_money_transaction_record.su_money) AS expend_su_money").
		Where(`su_money_transaction_record.employee @> '{"uid":?}'`, uid).
		Where(`su_money_transaction_record.record_type IN (?)`, pg.In([]int{1, 4})).
		Where(`su_money_transaction_record.create_time > ?`, transactionStartTime).
		Where(`su_money_transaction_record.create_time < ?`, transactionEndTime).
		Select(&expendSuMoney); err != nil {
		return nil, err
	}
	return map[string]interface{}{
		"incomeSuMoney": incomeSuMoney,
		"expendSuMoney": expendSuMoney,
	}, nil
}

// 员工财富值统计
func (dao *EmployeeDao) CalculateEmployeesSuMoney(companyId int, startTime time.Time, endTime time.Time) (map[string]interface{}, error) {
	tx := dao.transactionContext.PgTx
	var ret []struct {
		Uid int
		EmployeeName string
		EmployeeSuMoney float64
	}
	suMoneyTransactionRecordModel := new(models.SuMoneyTransactionRecord)
	if err := tx.Model(suMoneyTransactionRecordModel).Join("JOIN employees AS e ON e.uid = (su_money_transaction_record.employee->>'uid')::bigint").
		ColumnExpr("su_money_transaction_record.employee->>'uid' AS uid").
		ColumnExpr("su_money_transaction_record.employee->>'employeeName' AS employee_name").
		ColumnExpr("sum(su_money_transaction_record.su_money) AS employee_su_money").
		Where(`e.company_id = ?`, companyId).
		Where(`e.status = ?`, 1).
		Where(`su_money_transaction_record.record_type IN (?)`, pg.In([]int{2, 3})).  // 增加,任务奖励的
		Where(`su_money_transaction_record.create_time > ?`, startTime).
		Where(`su_money_transaction_record.create_time < ?`, endTime).
		Group("su_money_transaction_record.employee").
		Order("employee_su_money DESC").
		Select(&ret); err != nil {
			return nil, err
	}
	return map[string]interface{}{
		"employeesSuMoney": ret,
	}, nil
}

// 员工贡献值统计
func (dao *EmployeeDao) CalculateEmployeesContributions(companyId int, startTime time.Time, endTime time.Time) (map[string]interface{}, error) {
	tx := dao.transactionContext.PgTx
	var ret []struct {   // 员工贡献值
		Uid int
		EmployeeName string
		EmployeesContributions float64
	}
	var retDecrease []struct {  // 员工减少的贡献值
		Uid int
		EmployeeName string
		EmployeesContributions float64
	}
	suMoneyTransactionRecordModel := new(models.SuMoneyTransactionRecord)
	// 增加的贡献值
	if err := tx.Model(suMoneyTransactionRecordModel).Join("JOIN employees AS e ON e.uid = (su_money_transaction_record.employee->>'uid')::bigint").
		ColumnExpr("su_money_transaction_record.employee->>'uid' AS uid").
		ColumnExpr("su_money_transaction_record.employee->>'employeeName' AS employee_name").
		ColumnExpr("sum(su_money_transaction_record.su_money) AS employees_contributions").
		Where(`e.company_id = ?`, companyId).
		Where(`su_money_transaction_record.record_type IN (?)`, pg.In([]int{2, 3})).
		Where(`e.status = ?`, 1).
		Where(`su_money_transaction_record.create_time > ?`, startTime).
		Where(`su_money_transaction_record.create_time < ?`, endTime).
		Group("su_money_transaction_record.employee").
		Order("employees_contributions DESC").
		Select(&ret); err != nil {
		return nil, err
	}
	// 减少的贡献值
	if err := tx.Model(suMoneyTransactionRecordModel).Join("JOIN employees AS e ON e.uid = (su_money_transaction_record.employee->>'uid')::bigint").
		ColumnExpr("su_money_transaction_record.employee->>'uid' AS uid").
		ColumnExpr("su_money_transaction_record.employee->>'employeeName' AS employee_name").
		ColumnExpr("sum(su_money_transaction_record.su_money) AS employees_contributions").
		Where(`e.company_id = ?`, companyId).
		Where(`su_money_transaction_record.record_type = ?`, 4).
		Where(`e.status = ?`, 1).
		Where(`su_money_transaction_record.create_time > ?`, startTime).
		Where(`su_money_transaction_record.create_time < ?`, endTime).
		Group("su_money_transaction_record.employee").
		Order("employees_contributions DESC").
		Select(&retDecrease); err != nil {
		return nil, err
	}
	// merge两个贡献值
	for i := 0; i < len(ret); i++ {
		for j := 0; j < len(retDecrease); j++ {
			if ret[i].Uid == retDecrease[j].Uid {
				ret[i].EmployeesContributions -= retDecrease[j].EmployeesContributions
			}
		}
	}
	return map[string]interface{}{
		"employeesContributions": ret,
	}, nil
}

func NewEmployeeDao(transactionContext *pgTransaction.TransactionContext) (*EmployeeDao, error) {
	if transactionContext == nil {
		return nil, fmt.Errorf("transactionContext参数不能为nil")
	} else {
		return &EmployeeDao{
			transactionContext: transactionContext,
		}, nil
	}
}