package service import ( "enterprise/common/dao" "enterprise/common/model" log "github.com/sirupsen/logrus" "github.com/smbrave/goutil" "github.com/spf13/cast" "math" "strings" "time" ) type StaffUser struct { user *model.StaffUser corp *model.Corp month string vacations []*model.ApprovalVacation checkins []*model.Checkin } func NewStaffUser(user *model.StaffUser) *StaffUser { uv := &StaffUser{ user: user, } return uv } func (s *StaffUser) Load(month string) { corp, err := dao.NewCorpDao().Get(s.user.CorpId) if err != nil { log.Errorf("db error :%s", err.Error()) return } // 休假申请 approveVacations, err := dao.NewApprovalVacationDao().GetByUsername(s.user.CorpId, s.user.Username, month, "") if err != nil { log.Errorf("db error :%s", err.Error()) return } //打卡记录 userCheckins, err := dao.NewCheckinDao().Query(s.user.CorpId, s.user.Username, month, false) if err != nil { log.Errorf("db error :%s", err.Error()) return } s.vacations = approveVacations s.checkins = userCheckins s.corp = corp s.month = month } func (v *StaffUser) GetVacationDay() float64 { holiday := float64(0) for _, vac := range v.vacations { startTime, _ := time.ParseInLocation("2006-01-02 15:04:05", vac.VacationStartTime, time.Local) endTime, _ := time.ParseInLocation("2006-01-02 15:04:05", vac.VacationEndTime, time.Local) //同一天请假时长大于8小时算一天 if startTime.Format("2006-01-02") == endTime.Format("2006-01-02") && vac.VacationDuration > 1 { holiday += 1 } else { holiday += vac.VacationDuration } } return holiday } func (s *StaffUser) GetTotalWorkDay() int64 { return int64(len(s.checkins)) } func (s *StaffUser) GetRealWorkDay() float64 { realWorkdays := float64(0) //入职当天算工作日 entryTime, _ := time.ParseInLocation("2006-01-02", s.user.EntryDate, time.Local) if entryTime.Format("200601") == s.month { realWorkdays += 1 } //离职当天算工作日 leaveTime, _ := time.ParseInLocation("2006-01-02", s.user.LeaveDate, time.Local) if leaveTime.Format("200601") == s.month { realWorkdays += 1 } for _, checkin := range s.checkins { //有请假申请的不算出勤 if s.existVacation(checkin.Day) { continue } //入职离职当天已经算过了 if entryTime.Format("2006-01-02") == checkin.Day || leaveTime.Format("2006-01-02") == checkin.Day { continue } //有补卡记录的直接算出勤 if s.existApproveCheckin(checkin.Day) { realWorkdays += 1 continue } //考勤正常算出勤 if checkin.IsNormal() { realWorkdays += 1 continue } //其他情况按工作时长结算 if checkin.IsCheckin() { shouldAttendHour := cast.ToFloat64(s.corp.GetConfig().WorkerHour) lackSecond := int64(float64(3600)*(1.5+shouldAttendHour)) - (checkin.EndTime - checkin.StartTime) //加上午休的1.5小时 if lackSecond > 0 { lackHour := float64(lackSecond/3600 + 1) //按小时取整 realWorkdays += goutil.If(lackHour > shouldAttendHour, 0, 1-lackHour/shouldAttendHour) } else { realWorkdays += 1 } } } realWorkdays += s.getVacationSurplus() return realWorkdays } func (v *StaffUser) existVacation(day string) bool { queryDay := cast.ToInt(strings.ReplaceAll(day, "-", "")) for _, vac := range v.vacations { startTime, _ := time.ParseInLocation("2006-01-02 15:04:05", vac.VacationStartTime, time.Local) endTime, _ := time.ParseInLocation("2006-01-02 15:04:05", vac.VacationEndTime, time.Local) startDay := cast.ToInt(startTime.Format("20060102")) endDay := cast.ToInt(endTime.Format("20060102")) if queryDay >= startDay && queryDay <= endDay { return true } } return false } func (s *StaffUser) existApproveCheckin(day string) bool { //有补卡申请就直接算出勤 approvalCheckin, _ := dao.NewApprovalCheckinDao().GetByUsernameDay(s.user.CorpId, s.user.Username, day) if approvalCheckin != nil { return true } return false } func (s *StaffUser) getVacationSurplus() float64 { suplusDays := float64(0) vacationMap := make(map[string]float64) for _, vac := range s.vacations { startTime, _ := time.ParseInLocation("2006-01-02 15:04:05", vac.VacationStartTime, time.Local) endTime, _ := time.ParseInLocation("2006-01-02 15:04:05", vac.VacationEndTime, time.Local) startDay := startTime.Format("2006-01-02") endDay := endTime.Format("2006-01-02") if startDay == endDay { vacationMap[startDay] += vac.VacationDuration continue } span := vac.VacationDuration - math.Floor(vac.VacationDuration) suplusDays += goutil.If(span > 0, 1-span, 0) } for _, duration := range vacationMap { if duration < 1 { suplusDays += 1 - duration } } return suplusDays }