package models import ( "fmt" "github.com/shopspring/decimal" "gorm.io/gorm" "math/rand" "silkserver/constvar" "silkserver/pkg/mysqlx" "silkserver/utils" ) // 工时统计 type ( // PayrollWorkingHours 工资计算-员工的工时统计 PayrollWorkingHours struct { BaseModelInt Cycle string `json:"cycle" gorm:"index;size:20;not null;comment:统计周期(年月日)"` //统计周期(年月日) WorkTypeID uint `json:"workTypeID" gorm:"type:bigint(20);not null;comment:工种ID"` //工种ID WorkTypeCode constvar.JobType `json:"workTypeCode" gorm:"size:255;not null;comment:工种编码"` //工种编码 WorkType WorkTypeManage `json:"workType" gorm:"foreignKey:WorkTypeID;references:ID"` WorkerID string `json:"workerId" gorm:"size:200;not null;comment:员工ID"` //员工ID Worker Worker `json:"worker" gorm:"foreignKey:WorkerID;references:ID"` WorkshopId uint `json:"workshopId" gorm:"type:int(11);comment:车间Id"` WorkshopNumber string `json:"workshopNumber" gorm:"size:255;not null;comment:车间编号"` // 车间编号 GroupNumber int `json:"groupNumber" gorm:"size:11;not null;comment:组别"` // 组别 StartCarNumber int `json:"startCarNumbers" gorm:"size:11;comment:车台号开始"` // 车台号列表 EndCarNumber int `json:"endCarNumbers" gorm:"size:11;comment:车台号结束"` // 车台号列表 ShiftTime string `json:"shiftStartTime" gorm:"size:100;comment:班次时间段" ` // 班次时间段 ShiftCrossDay bool `json:"shiftCrossDay" gorm:"size:1;comment:是否为跨天班次" ` // 是否为跨天班次 ShiftClockInTime string `json:"shiftClockInTime" gorm:"size:50;comment:上班打卡时间" ` // 上班打卡时间 ShiftClockOutTime string `json:"shiftClockOutTime" gorm:"size:50;comment:下班打卡时间" ` // 下班打卡时间 OvertimeType constvar.ShiftOvertimeType `json:"overtimeType" gorm:"size:50;comment:加班类型" ` // 加班类型 OvertimeDuration decimal.Decimal `json:"overtimeDuration" gorm:"type:decimal(12,4);comment:加班时长" ` // 加班时长 OvertimePay decimal.Decimal `json:"overtimePay" gorm:"type:decimal(12,4);comment:加班工资"` // 加班工资 } PayrollWorkingHoursSearch struct { PayrollWorkingHours Monthly string Order string PageNum int PageSize int Preload bool Orm *gorm.DB } ) func (slf PayrollWorkingHours) TableName() string { return "silk_payroll_working_hours" } // NewPayrollWorkingHoursSearch 员工的工时统计 func NewPayrollWorkingHoursSearch() *PayrollWorkingHoursSearch { return &PayrollWorkingHoursSearch{Orm: mysqlx.GetDB()} } func (slf *PayrollWorkingHoursSearch) SetOrm(tx *gorm.DB) *PayrollWorkingHoursSearch { slf.Orm = tx return slf } func (slf *PayrollWorkingHoursSearch) SetPage(page, size int) *PayrollWorkingHoursSearch { slf.PageNum, slf.PageSize = page, size return slf } func (slf *PayrollWorkingHoursSearch) SetOrder(order string) *PayrollWorkingHoursSearch { slf.Order = order return slf } func (slf *PayrollWorkingHoursSearch) SetID(id uint) *PayrollWorkingHoursSearch { slf.ID = id return slf } func (slf *PayrollWorkingHoursSearch) SetCycle(cycle string) *PayrollWorkingHoursSearch { slf.Cycle = cycle return slf } func (slf *PayrollWorkingHoursSearch) SetMonthly(monthly string) *PayrollWorkingHoursSearch { slf.Monthly = monthly return slf } func (slf *PayrollWorkingHoursSearch) SetWorkTypeID(workTypeID uint) *PayrollWorkingHoursSearch { slf.WorkTypeID = workTypeID return slf } func (slf *PayrollWorkingHoursSearch) SetWorkTypeCode(workTypeCode constvar.JobType) *PayrollWorkingHoursSearch { slf.WorkTypeCode = workTypeCode return slf } func (slf *PayrollWorkingHoursSearch) SetWorkerID(workerID string) *PayrollWorkingHoursSearch { slf.WorkerID = workerID return slf } func (slf *PayrollWorkingHoursSearch) SetWorkshopNumber(workshopNumber string) *PayrollWorkingHoursSearch { slf.WorkshopNumber = workshopNumber return slf } func (slf *PayrollWorkingHoursSearch) SetGroupNumber(groupNumber int) *PayrollWorkingHoursSearch { slf.GroupNumber = groupNumber return slf } func (slf *PayrollWorkingHoursSearch) build() *gorm.DB { var db = slf.Orm.Table(slf.TableName()) if slf.Preload { db = db.Model(&PayrollWorkingHours{}).Preload("Worker").Preload("WorkTypeManage") } if slf.ID > 0 { db = db.Where("id = ?", slf.ID) } if slf.Cycle != "" { db = db.Where("cycle = ?", slf.Cycle) } if slf.Monthly != "" { db = db.Where("cycle like ?", slf.Monthly+"%") } if slf.WorkTypeID > 0 { db = db.Where("work_type_id = ?", slf.WorkTypeID) } if slf.WorkTypeCode != "" { db = db.Where("work_type_code = ?", slf.WorkTypeCode) } if slf.WorkerID != "" { db = db.Where("worker_id = ?", slf.WorkerID) } if slf.WorkshopNumber != "" { db = db.Where("workshop_number = ?", slf.WorkshopNumber) } if slf.GroupNumber > 0 { db = db.Where("group_number = ?", slf.GroupNumber) } db.Where("1 = 1") if slf.Order != "" { db = db.Order(slf.Order) } return db } // Create 单条插入 func (slf *PayrollWorkingHoursSearch) Create(record *PayrollWorkingHours) error { var db = slf.build() if err := db.Create(record).Error; err != nil { return fmt.Errorf("create err: %v, record: %+v", err, record) } return nil } // CreateBatch 批量插入 func (slf *PayrollWorkingHoursSearch) CreateBatch(records []*PayrollWorkingHours) error { var db = slf.build() if err := db.Create(&records).Error; err != nil { return fmt.Errorf("create batch err: %v, records: %+v", err, records) } return nil } // Save 单条更新 func (slf *PayrollWorkingHoursSearch) Save(record *PayrollWorkingHours) error { var db = slf.build() if err := db.Omit("CreatedAt").Save(record).Error; err != nil { return fmt.Errorf("save err: %v, record: %+v", err, record) } return nil } // SaveBatch 批量更新 func (slf *PayrollWorkingHoursSearch) SaveBatch(record []*PayrollWorkingHours) error { var db = slf.build() if err := db.Omit("CreatedAt").Save(record).Error; err != nil { return fmt.Errorf("save err: %v, record: %+v", err, record) } return nil } // UpdateByMap 单条更新 func (slf *PayrollWorkingHoursSearch) UpdateByMap(upMap map[string]interface{}) error { var ( db = slf.build() ) if err := db.Updates(upMap).Error; err != nil { return fmt.Errorf("update by map err: %v, upMap: %+v", err, upMap) } return nil } // UpdateByQuery 批量更新 func (slf *PayrollWorkingHoursSearch) UpdateByQuery(query string, args []interface{}, upMap map[string]interface{}) error { var ( db = slf.Orm.Table(slf.TableName()).Where(query, args...) ) if err := db.Updates(upMap).Error; err != nil { return fmt.Errorf("update by query err: %v, query: %s, args: %+v, upMap: %+v", err, query, args, upMap) } return nil } // Delete 删除 func (slf *PayrollWorkingHoursSearch) Delete() error { var db = slf.build() if err := db.Unscoped().Delete(&PayrollWorkingHours{}).Error; err != nil { return err } return nil } // First 根据条件查询一条记录 func (slf *PayrollWorkingHoursSearch) First() (*PayrollWorkingHours, error) { var ( record = new(PayrollWorkingHours) db = slf.build() ) if err := db.First(record).Error; err != nil { return record, err } return record, nil } // Find 指定条件查询(包含总条数) func (slf *PayrollWorkingHoursSearch) Find() ([]*PayrollWorkingHours, int64, error) { var ( records = make([]*PayrollWorkingHours, 0) total int64 db = slf.build() ) if err := db.Count(&total).Error; err != nil { return records, total, fmt.Errorf("find count err: %v", err) } if slf.PageNum*slf.PageSize > 0 { db = db.Offset((slf.PageNum - 1) * slf.PageSize).Limit(slf.PageSize) } if err := db.Find(&records).Error; err != nil { return records, total, fmt.Errorf("find records err: %v", err) } return records, total, nil } // FindNotTotal 指定条件查询 func (slf *PayrollWorkingHoursSearch) FindNotTotal() ([]*PayrollWorkingHours, error) { var ( records = make([]*PayrollWorkingHours, 0) db = slf.build() ) if slf.PageNum*slf.PageSize > 0 { db = db.Offset((slf.PageNum - 1) * slf.PageSize).Limit(slf.PageSize) } if err := db.Find(&records).Error; err != nil { return records, fmt.Errorf("find records err: %v", err) } return records, nil } // FindByQuery 指定条件查询(包含总条数) func (slf *PayrollWorkingHoursSearch) FindByQuery(query string, args []interface{}) ([]*PayrollWorkingHours, int64, error) { var ( records = make([]*PayrollWorkingHours, 0) total int64 db = slf.Orm.Table(slf.TableName()).Where(query, args...) ) if err := db.Count(&total).Error; err != nil { return records, total, fmt.Errorf("find by query count err: %v", err) } if slf.PageNum*slf.PageSize > 0 { db = db.Offset((slf.PageNum - 1) * slf.PageSize).Limit(slf.PageSize) } if err := db.Find(&records).Error; err != nil { return records, total, fmt.Errorf("find by query records err: %v, query: %s, args: %+v", err, query, args) } return records, total, nil } // FindByQueryNotTotal 指定条件查询&不查询总条数. func (slf *PayrollWorkingHoursSearch) FindByQueryNotTotal(query string, args []interface{}) ([]*PayrollWorkingHours, error) { var ( records = make([]*PayrollWorkingHours, 0) db = slf.Orm.Table(slf.TableName()).Where(query, args...) ) if slf.PageNum*slf.PageSize > 0 { db = db.Offset((slf.PageNum - 1) * slf.PageSize).Limit(slf.PageSize) } if err := db.Find(&records).Error; err != nil { return records, fmt.Errorf("find by query records err: %v, query: %s, args: %+v", err, query, args) } return records, nil } type GroupWorker struct { Cycle string `json:"cycle"` // 统计周期(年月日) WorkTypeCode constvar.JobType `json:"workTypeCode"` // 工种编码 WorkshopNumber string `json:"workshopNumber"` // 车间编号 GroupNumber int `json:"groupNumber"` // 组别 WorkerIds string `json:"workerIds"` // 员工ID WorkerCount int `json:"workerCount"` // 挡车工数量 } // GroupWorker 每天小组人员 func (slf *PayrollWorkingHoursSearch) GroupWorker(monthly string, workTypeCode constvar.JobType) ([]*GroupWorker, error) { var ( records = make([]*GroupWorker, 0) db = slf.Orm.Table(slf.TableName()) ) db.Select("cycle, work_type_code, workshop_number, group_number, group_concat(worker_id) as worker_ids, count(id) as worker_count") db.Where("cycle like ?", monthly+"%") if workTypeCode != "" { db.Where("work_type_code = ?", workTypeCode) } db.Group("cycle, work_type_code, workshop_number, group_number") return records, db.Find(&records).Error } // InitDefaultData 初始化数据 func (slf *PayrollWorkingHoursSearch) InitDefaultData() error { var ( db = slf.Orm.Table(slf.TableName()) total int64 = 0 ) firstDay, lastDay := utils.GetLastMonthPeriod(utils.GetMonthByOffset(-1)) for i := 0; i < (lastDay.Day()); i++ { date := firstDay.AddDate(0, 0, i) if err := db.Where("cycle = ?", date.Format("2006-01-02")).Count(&total).Error; err != nil { return err } if total != 0 { return nil } data := make([]*PayrollWorkingHours, 0) workers, _ := NewWorkerSearch().FindNotTotal() workshop := rand.Intn(10) for _, record := range workers { round := rand.Intn(10) info := PayrollWorkingHours{ Cycle: date.Format("2006-01-02"), WorkTypeID: uint(round + 1), WorkTypeCode: constvar.JobTypeArr[round], WorkerID: record.ID, WorkshopId: uint(workshop + 1), WorkshopNumber: fmt.Sprintf("100%v", workshop), GroupNumber: round, StartCarNumber: round*10 + 1, EndCarNumber: (round + 1) * 10, ShiftTime: "08:00-18:00", ShiftCrossDay: false, ShiftClockInTime: fmt.Sprintf("07:5%v", round), ShiftClockOutTime: fmt.Sprintf("20:0%v", round), } //if info.WorkTypeCode == constvar.JobTypeWeavers { // info.StartCarNumber = i*10 + 1 // info.EndCarNumber = (i + 1) * 10 //} if date.Weekday() == 0 { info.OvertimeType = constvar.ShiftOvertimeTypeOvertime info.OvertimeDuration = decimal.NewFromInt32(1) info.OvertimePay = decimal.NewFromInt32(1 * 90) } else { info.OvertimeType = constvar.ShiftOvertimeTypeTimeout info.OvertimeDuration = decimal.NewFromInt32(int32(workshop)) info.OvertimePay = decimal.NewFromInt32(int32(workshop * 12)) } data = append(data, &info) } if err := slf.CreateBatch(data); err != nil { return err } } return nil }