package task
|
|
import (
|
"errors"
|
"github.com/shopspring/decimal"
|
"silkserver/constvar"
|
"silkserver/models"
|
"silkserver/pkg/logx"
|
"silkserver/utils"
|
"strings"
|
"time"
|
)
|
|
func SalaryStatistics() {
|
//加锁,只需要一个进程运行此任务
|
var (
|
lockName = "SalaryStatistics"
|
serviceID = "silkServer"
|
)
|
err := models.NewLockSearch().AcquireLock(lockName, serviceID)
|
if err != nil {
|
logx.Errorf("MonthStats AcquireLock err:%v", err)
|
return
|
}
|
defer func() {
|
err := models.NewLockSearch().ReleaseLock(lockName, serviceID)
|
if err != nil {
|
logx.Errorf("MonthStats ReleaseLock err:%v", err)
|
}
|
}()
|
|
lastMonthStart, lastMonthEnd := GetLastMonthPeriod()
|
month := lastMonthStart.Format("2006-01")
|
|
//查询考勤统计
|
startStr := lastMonthStart.Format("2006-01-02")
|
endStr := lastMonthEnd.Format("2006-01-02")
|
attendances, err := models.NewAttendanceManageSearch().SetMonth(month).FindNotTotal()
|
if err != nil {
|
logx.Error("SalaryStatistics 查询考勤统计 err: " + err.Error())
|
return
|
}
|
if len(attendances) == 0 {
|
logx.Warn("SalaryStatistics 查询考勤统计 empty result")
|
return
|
}
|
|
var reportForms []*models.SalaryReportForm
|
reportMap := make(map[string]*models.SalaryReportForm)
|
workTypeIdMap := make(map[uint]uint)
|
dataMap := make(map[string]utils.SalaryCalculateData)
|
for _, attendance := range attendances {
|
if _, ok := reportMap[attendance.WorkerId]; !ok {
|
var rf models.SalaryReportForm
|
rf.WorkerId = attendance.WorkerId
|
rf.WorkerName = attendance.WorkerName
|
rf.WorkTypeId = attendance.WorkTypeId
|
rf.Month = month
|
rf.Phone = attendance.PhoneNum
|
reportMap[attendance.WorkerId] = &rf
|
}
|
var data utils.SalaryCalculateData
|
if _, ok := dataMap[attendance.WorkerId]; ok {
|
data = dataMap[attendance.WorkerId]
|
}
|
if attendance.WorkTypeId > 0 {
|
workTypeIdMap[attendance.WorkTypeId] = attendance.WorkTypeId
|
}
|
//工作日加班时长
|
data.WeekdayOvertimeHours = data.WeekdayOvertimeHours.Add(attendance.OverTimeDuration)
|
//出勤天数
|
if attendance.Status != constvar.Vacation {
|
data.TotalAttendanceDays = data.TotalAttendanceDays + 1
|
}
|
dataMap[attendance.WorkerId] = data
|
}
|
for _, v := range reportMap {
|
reportForms = append(reportForms, v)
|
}
|
workTypeIds := make([]uint, 0)
|
for _, v := range workTypeIdMap {
|
workTypeIds = append(workTypeIds, v)
|
}
|
|
//查询工种的薪资方案和新增类型
|
workTypeManages, err := models.NewWorkTypeManageSearch().SetIds(workTypeIds).SetPreload(true).FindNotTotal()
|
if err != nil {
|
logx.Error("SalaryStatistics 查询工种的薪资方案和新增类型 err: " + err.Error())
|
return
|
}
|
if len(workTypeManages) == 0 {
|
return
|
}
|
for _, form := range reportForms {
|
details := make([]*models.SalaryDetails, 0)
|
issueSalary := decimal.NewFromInt(0)
|
for _, manage := range workTypeManages {
|
if form.WorkTypeId == manage.ID {
|
data := dataMap[form.WorkerId]
|
for _, plan := range manage.SalaryPlans {
|
formula := strings.ReplaceAll(plan.SalaryFormula, ",", "")
|
var detail models.SalaryDetails
|
detail.SalaryTypeId = plan.SalaryTypeId
|
amount := decimal.NewFromInt(0)
|
f := constvar.DailySilkProduction + "*" + constvar.RawSilkUnitPrice
|
if strings.Contains(formula, f) {
|
data, err = GetDailySilkProduction(startStr, endStr, form.WorkerId, data)
|
if err != nil {
|
logx.Error("SalaryStatistics 统计薪资出错 err: " + err.Error())
|
}
|
}
|
amount, err = utils.CalculateSalary(data, formula)
|
if err != nil {
|
logx.Error("SalaryStatistics 计算薪资出错 err: " + err.Error())
|
}
|
detail.Amount = amount
|
issueSalary = issueSalary.Add(amount)
|
details = append(details, &detail)
|
}
|
}
|
}
|
form.Details = details
|
form.IssueSalary = issueSalary
|
}
|
|
//插入数据库
|
err = models.NewSalaryReportFormSearch().CreateBatch(reportForms)
|
if err != nil {
|
logx.Error("SalaryStatistics 插入数据库出错 err: " + err.Error())
|
}
|
}
|
|
func GetDailySilkProduction(start, end, workerId string, data utils.SalaryCalculateData) (utils.SalaryCalculateData, error) {
|
//查询机台管理
|
var cars []models.WorkerPosition
|
err := models.NewWorkerPositionSearch().Orm.Table("silk_worker_position").Where("worker_id = ? and start_date >= ? and "+
|
"end_date <= ?", workerId, start, end).Find(&cars).Error
|
if err != nil || len(cars) == 0 {
|
return data, errors.New("查询机台管理出错")
|
}
|
endCarMap := make(map[int]int)
|
groupMap := make(map[int]int)
|
workshopMap := make(map[string]string)
|
for _, car := range cars {
|
endCarMap[car.EndWorkerPosition] = car.EndWorkerPosition
|
groupMap[car.WorkshopGroup] = car.WorkshopGroup
|
workshopMap[car.Workshop] = car.Workshop
|
}
|
groups := make([]int, 0)
|
workshops := make([]string, 0)
|
endCars := make([]int, 0)
|
for _, v := range endCarMap {
|
endCars = append(endCars, v)
|
}
|
for _, v := range workshopMap {
|
workshops = append(workshops, v)
|
}
|
for _, v := range groupMap {
|
groups = append(groups, v)
|
}
|
|
//查询产量登记表
|
var yield []models.YieldRegister
|
err = models.NewYieldRegisterSearch().Orm.Table("silk_yield_register").Where("workshop_number in (?) and group_number "+
|
"in (?) and create_time >= ? and create_time <= ?", workshops, groups, start, end).Find(&yield).Error
|
if err != nil || len(yield) == 0 {
|
return data, errors.New("查询产量登记表出错")
|
}
|
yieldRegisterIds := make([]uint, 0)
|
for _, register := range yield {
|
yieldRegisterIds = append(yieldRegisterIds, register.ID)
|
}
|
yieldMap := make(map[string]decimal.Decimal)
|
items, err := models.NewYieldRegisterItemSearch().SetYieldRegisterIds(yieldRegisterIds).SetCarNumbers(endCars).FindNotTotal()
|
if err != nil || len(items) == 0 {
|
return data, errors.New("查询产量登记详情表出错")
|
}
|
for _, register := range yield {
|
for _, item := range items {
|
if register.ID == item.YieldRegisterId {
|
yieldMap[register.CreateTime] = item.PeopleYield
|
}
|
}
|
}
|
//查询纤度登记表
|
var fineness []models.FinenessRegister
|
markets := make([]string, 0)
|
err = models.NewFinenessRegisterSearch().Orm.Table("silk_fineness_register").Where("workshop_number in (?) and workshop_group "+
|
"in (?) and finish_date >= ? and finish_date <= ?", workshops, groups, start, end).Find(&fineness).Error
|
if err != nil || len(fineness) == 0 {
|
return data, errors.New("查询纤度登记表出错")
|
}
|
finenessIds := make([]uint, 0)
|
for _, register := range fineness {
|
finenessIds = append(finenessIds, register.ID)
|
markets = append(markets, register.Market)
|
}
|
var checkItems []models.FinenessCheckItem
|
err = models.NewFinenessCheckItemSearch().Orm.Table("silk_fineness_check_item").Where("fineness_register_id in (?) and "+
|
"position in (?)", finenessIds, endCars).Find(&checkItems).Error
|
if err != nil || len(checkItems) == 0 {
|
return data, errors.New("查询纤度登记详情表出错")
|
}
|
checkMap := make(map[string]string)
|
marketMap := make(map[string]string)
|
for _, item := range checkItems {
|
for _, register := range fineness {
|
if item.FinenessRegisterID == register.ID {
|
checkMap[register.FinishDate] = item.FinenessGrade
|
marketMap[register.FinishDate] = register.Market
|
break
|
}
|
}
|
}
|
//查询不同庄口下的生丝定价
|
find, _, err := models.NewRawSilkPriceStandardSearch().SetMarketNames(markets).Find()
|
if err != nil {
|
return data, err
|
}
|
//计算每日工资
|
total := decimal.NewFromInt(0)
|
for date, amount := range yieldMap {
|
grade := checkMap[date]
|
market := marketMap[date]
|
for _, standard := range find {
|
if standard.MarketName == market && standard.RawSilkGrade == grade {
|
h := amount.Mul(standard.PayStandard)
|
total = total.Add(h)
|
break
|
}
|
}
|
}
|
data.DailySilkProduction = total
|
data.RawSilkUnitPrice = decimal.NewFromInt(1)
|
return data, nil
|
}
|
|
// GetLastMonthPeriod 返回上个月的月初时间和月末时间
|
func GetLastMonthPeriod() (time.Time, time.Time) {
|
// 获取当前时间
|
now := time.Now()
|
|
// 计算上个月的年份和月份
|
lastMonth := now.AddDate(0, -1, 0)
|
lastYear, lastMonthNum, _ := lastMonth.Date()
|
|
// 获取上个月的第一天的日期(即上个月月初)
|
firstDayOfLastMonth := time.Date(lastYear, lastMonthNum, 1, 0, 0, 0, 0, now.Location())
|
|
// 获取本月第一天的日期(即本月月初)
|
firstDayOfThisMonth := time.Date(now.Year(), now.Month(), 1, 0, 0, 0, 0, now.Location())
|
|
// 上个月月末时间即为本月月初减去一秒
|
lastDayOfLastMonth := firstDayOfThisMonth.Add(-time.Second)
|
|
return firstDayOfLastMonth, lastDayOfLastMonth
|
}
|