staff_user2
This commit is contained in:
parent
9868bd0923
commit
5e9ac840b4
|
@ -42,5 +42,8 @@ func (c *Corp) GetConfig() *CorpConfig {
|
|||
var cfg CorpConfig
|
||||
json.Unmarshal([]byte(c.Config), &cfg)
|
||||
|
||||
if cfg.WorkerHour == "" {
|
||||
cfg.WorkerHour = "8"
|
||||
}
|
||||
return &cfg
|
||||
}
|
||||
|
|
|
@ -9,7 +9,6 @@ import (
|
|||
log "github.com/sirupsen/logrus"
|
||||
"github.com/smbrave/goutil"
|
||||
"github.com/spf13/cast"
|
||||
"math"
|
||||
"time"
|
||||
)
|
||||
|
||||
|
@ -62,6 +61,7 @@ func (s *StaffSalary) CalcSalary(salary *model.StaffSalary, month, expr string)
|
|||
salary.Username = s.user.Username
|
||||
salary.Status = model.StaffSalaryStatusWait
|
||||
}
|
||||
|
||||
//已支付过的工资不能再计算了
|
||||
if salary != nil && salary.Status == model.StaffSalaryStatusPayed {
|
||||
return salary, nil
|
||||
|
@ -75,7 +75,10 @@ func (s *StaffSalary) CalcSalary(salary *model.StaffSalary, month, expr string)
|
|||
salary.HouseDeduct = 0
|
||||
}
|
||||
|
||||
salary.ShouldDay = int(s.getTotalWorkDay(s.user.CorpId, s.user.Username, month))
|
||||
staffUser := NewStaffUser(s.user)
|
||||
staffUser.Load(month)
|
||||
|
||||
salary.ShouldDay = int(staffUser.GetTotalWorkDay())
|
||||
// 入职月或离职月以大多数人的出勤天数为准
|
||||
if isEntryMonth || isLeaveMonth {
|
||||
salary.ShouldDay = int(s.getTotalWorkDayMax(s.user.CorpId, month))
|
||||
|
@ -85,16 +88,9 @@ func (s *StaffSalary) CalcSalary(salary *model.StaffSalary, month, expr string)
|
|||
salary.ShouldDay = 22
|
||||
}
|
||||
|
||||
holiday, surplusHoliday := s.getRealVacationDay(month)
|
||||
realWorkDays := s.getRealWorkDay(month)
|
||||
//approvalCheckinDay := s.getApprovalCheckinDay(s.user.CorpId, s.user.Username, month)
|
||||
salary.HolidayDay = staffUser.GetVacationDay()
|
||||
salary.AttendDay = staffUser.GetRealWorkDay()
|
||||
|
||||
//鱼办特殊月份
|
||||
if salary.Month == "202502" && corp.Id == 1002 {
|
||||
salary.ShouldDay = 21
|
||||
}
|
||||
salary.HolidayDay = holiday
|
||||
salary.AttendDay = realWorkDays + surplusHoliday
|
||||
salary.Salary = cast.ToFloat64(userSalary.Base) + cast.ToFloat64(userSalary.Target)
|
||||
salary.SocialDeduct = goutil.If(userConfig.SocialDeduct != "", cast.ToFloat64(userConfig.SocialDeduct), cast.ToFloat64(corpConfig.SocialDeduct))
|
||||
salary.HouseDeduct = goutil.If(userConfig.HouseDeduct != "", cast.ToFloat64(userConfig.HouseDeduct), cast.ToFloat64(corpConfig.HouseDeduct))
|
||||
|
@ -204,125 +200,6 @@ func (s *StaffSalary) formatFloat(salary *model.StaffSalary) {
|
|||
salary.HolidayDay = butil.FloatCut(salary.HolidayDay)
|
||||
}
|
||||
|
||||
func (s *StaffSalary) getRealVacationDay(month string) (float64, float64) {
|
||||
// 休假申请
|
||||
approveVacations, err := dao.NewApprovalVacationDao().GetByUsername(s.user.CorpId, s.user.Username, month, "")
|
||||
if err != nil {
|
||||
log.Errorf("db error :%s", err.Error())
|
||||
return 0, 0
|
||||
}
|
||||
|
||||
holiday := float64(0)
|
||||
surplusHoliday := float64(0)
|
||||
holidayMap := make(map[string]float64)
|
||||
for _, vac := range approveVacations {
|
||||
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
|
||||
//不是整天数,把剩余的算上
|
||||
if _, ok := holidayMap[vac.VacationDate]; !ok {
|
||||
span := vac.VacationDuration - math.Floor(vac.VacationDuration)
|
||||
if _, ok := holidayMap[vac.VacationDate]; !ok {
|
||||
holidayMap[vac.VacationDate] = goutil.If(math.Abs(span) < 0.000001, 0, 1-span)
|
||||
} else {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
return holiday, surplusHoliday
|
||||
}
|
||||
|
||||
func (s *StaffSalary) getApprovalCheckinDay(corpId int64, username, month string) int {
|
||||
approvalDay := int(0)
|
||||
userCheckins, err := dao.NewCheckinDao().Query(corpId, username, month, false)
|
||||
if err != nil {
|
||||
log.Errorf("db error :%s", err.Error())
|
||||
return approvalDay
|
||||
}
|
||||
for _, checkin := range userCheckins {
|
||||
approvalCheckin, _ := dao.NewApprovalCheckinDao().GetByUsernameDay(corpId, username, checkin.Day)
|
||||
if approvalCheckin != nil {
|
||||
approvalDay += 1
|
||||
}
|
||||
|
||||
}
|
||||
return approvalDay
|
||||
}
|
||||
|
||||
func (s *StaffSalary) getRealWorkDay(month string) float64 {
|
||||
realWorkdays := float64(0)
|
||||
userCheckins, err := dao.NewCheckinDao().Query(s.user.CorpId, s.user.Username, month, false)
|
||||
if err != nil {
|
||||
log.Errorf("db error :%s", err.Error())
|
||||
return realWorkdays
|
||||
}
|
||||
approvalCheckinDay := 0
|
||||
|
||||
//入职当天算工作日
|
||||
entryTime, _ := time.ParseInLocation("2006-01-02", s.user.EntryDate, time.Local)
|
||||
if entryTime.Format("200601") == month {
|
||||
realWorkdays += 1
|
||||
}
|
||||
|
||||
//离职当天算工作日
|
||||
leaveTime, _ := time.ParseInLocation("2006-01-02", s.user.LeaveDate, time.Local)
|
||||
if leaveTime.Format("200601") == month {
|
||||
realWorkdays += 1
|
||||
}
|
||||
|
||||
corp, _ := dao.NewCorpDao().Get(s.user.CorpId)
|
||||
for _, checkin := range userCheckins {
|
||||
//入职离职当天已经算过了
|
||||
if entryTime.Format("2006-01-02") == checkin.Day || leaveTime.Format("2006-01-02") == checkin.Day {
|
||||
continue
|
||||
}
|
||||
|
||||
//有请假申请的不算出勤
|
||||
approvalVacation, _ := dao.NewApprovalVacationDao().GetByUsernameDay(s.user.CorpId, s.user.Username, checkin.Day)
|
||||
if approvalVacation != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
if checkin.IsNormal() {
|
||||
realWorkdays += 1
|
||||
continue
|
||||
}
|
||||
|
||||
//有补卡申请就直接算出勤
|
||||
approvalCheckin, _ := dao.NewApprovalCheckinDao().GetByUsernameDay(s.user.CorpId, s.user.Username, checkin.Day)
|
||||
if approvalCheckin != nil {
|
||||
realWorkdays += 1
|
||||
approvalCheckinDay += 1
|
||||
continue
|
||||
}
|
||||
|
||||
//其他按工作时长结算
|
||||
if checkin.IsCheckin() {
|
||||
shouldAttendHour := cast.ToFloat64(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
|
||||
}
|
||||
}
|
||||
}
|
||||
return realWorkdays
|
||||
}
|
||||
|
||||
func (s *StaffSalary) getTotalWorkDay(corpId int64, username, month string) int64 {
|
||||
checkins, _ := dao.NewCheckinDao().Query(corpId, username, month, false)
|
||||
return int64(len(checkins))
|
||||
}
|
||||
|
||||
func (s *StaffSalary) getTotalWorkDayMax(corpId int64, month string) int64 {
|
||||
// 最多人数的应出勤天数 为真正的出勤天数
|
||||
userCounts, err := dao.NewCheckinDao().CountUsername(corpId, month)
|
||||
|
@ -343,5 +220,4 @@ func (s *StaffSalary) getTotalWorkDayMax(corpId int64, month string) int64 {
|
|||
}
|
||||
}
|
||||
return totalDays
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,182 @@
|
|||
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
|
||||
}
|
|
@ -1,13 +0,0 @@
|
|||
package service
|
||||
|
||||
import "enterprise/common/model"
|
||||
|
||||
type StaffUserCheckin struct {
|
||||
user *model.StaffUser
|
||||
}
|
||||
|
||||
func NewStaffUserCheckin(user *model.StaffUser) *StaffUserCheckin {
|
||||
return &StaffUserCheckin{
|
||||
user: user,
|
||||
}
|
||||
}
|
|
@ -1,107 +0,0 @@
|
|||
package service
|
||||
|
||||
import (
|
||||
"enterprise/common/dao"
|
||||
"enterprise/common/model"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"time"
|
||||
)
|
||||
|
||||
type StaffUserVacation struct {
|
||||
user *model.StaffUser
|
||||
corp *model.Corp
|
||||
month string
|
||||
|
||||
vacations []*model.ApprovalVacation
|
||||
vacationsMap map[string]float64
|
||||
}
|
||||
|
||||
func NewStaffUserVacation(corp *model.Corp, user *model.StaffUser, month string) *StaffUserVacation {
|
||||
uv := &StaffUserVacation{
|
||||
user: user,
|
||||
corp: corp,
|
||||
month: month,
|
||||
vacationsMap: make(map[string]float64),
|
||||
}
|
||||
|
||||
uv.loadArr()
|
||||
uv.loadMaps()
|
||||
return uv
|
||||
}
|
||||
|
||||
func (v *StaffUserVacation) loadMaps() {
|
||||
vacationMap := make(map[string]float64)
|
||||
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 := startTime.Format("2006-01-02")
|
||||
endDay := endTime.Format("2006-01-02")
|
||||
if startDay == endDay {
|
||||
vacationMap[startDay] += vac.VacationDuration
|
||||
continue
|
||||
}
|
||||
|
||||
day := startTime.Format("2006-01-02")
|
||||
for {
|
||||
|
||||
if day == startDay {
|
||||
|
||||
}
|
||||
|
||||
if day == endDay {
|
||||
|
||||
break
|
||||
}
|
||||
|
||||
startTime = startTime.AddDate(0, 0, 1)
|
||||
day = startTime.Format("2006-01-02")
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
//每天请假时长不超过1天
|
||||
for k, duration := range vacationMap {
|
||||
if duration > 1 {
|
||||
vacationMap[k] = 1
|
||||
}
|
||||
}
|
||||
v.vacationsMap = vacationMap
|
||||
return
|
||||
}
|
||||
|
||||
func (v *StaffUserVacation) loadArr() {
|
||||
// 休假申请
|
||||
approveVacations, err := dao.NewApprovalVacationDao().GetByUsername(v.user.CorpId, v.user.Username, v.month, "")
|
||||
if err != nil {
|
||||
log.Errorf("db error :%s", err.Error())
|
||||
return
|
||||
}
|
||||
v.vacations = approveVacations
|
||||
}
|
||||
|
||||
func (v *StaffUserVacation) GetTotalDay() 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 (v *StaffUserVacation) GetSurplusDay() float64 {
|
||||
suplusDays := float64(0)
|
||||
for _, duration := range v.vacationsMap {
|
||||
if duration < 1 {
|
||||
suplusDays += 1 - duration
|
||||
}
|
||||
}
|
||||
return suplusDays
|
||||
}
|
Loading…
Reference in New Issue