new sallary

This commit is contained in:
jiangyong27 2024-01-31 20:49:43 +08:00
parent 5d99b471bc
commit b676aa9707
8 changed files with 136 additions and 83 deletions

View File

@ -3,12 +3,11 @@ package main
import ( import (
"enterprise/common/config" "enterprise/common/config"
"enterprise/common/global" "enterprise/common/global"
"enterprise/common/model"
"enterprise/server" "enterprise/server"
"enterprise/worker" "enterprise/worker"
) )
func main() { func main22() {
config.LoadServerConfig() config.LoadServerConfig()
global.InitGlobal() global.InitGlobal()
@ -21,11 +20,12 @@ func main() {
} }
} }
func main22() { func main() {
config.LoadServerConfig() config.LoadServerConfig()
global.InitGlobal() global.InitGlobal()
//cfg := config.GetConfig() //cfg := config.GetConfig()
//new(worker.Checkin).SyncCheckinDay("2024-01-17") //new(worker.Checkin).SyncCheckinDay("2024-01-17")
new(worker.Approval).Sync("202401", model.ApprovalTypeRefund) //new(worker.Approval).Sync("202401", model.ApprovalTypeRefund)
new(worker.Staff).SyncStaffSalary("202401")
} }

View File

@ -64,3 +64,15 @@ func (d *ApprovalCheckinDao) GetBySpNo(spNo string) (*model.ApprovalCheckin, err
} }
return &u, nil return &u, nil
} }
func (d *ApprovalCheckinDao) GetByUsername(username, month string) ([]*model.ApprovalCheckin, error) {
var u []*model.ApprovalCheckin
tx := GetDB().Table(d.TableName())
tx = tx.Where("month = ?", month)
tx = tx.Where("username = ?", username)
res := tx.Find(&u)
if res.Error != nil {
return nil, res.Error
}
return u, nil
}

View File

@ -64,3 +64,15 @@ func (d *ApprovalVacationDao) GetBySpNo(spNo string) (*model.ApprovalVacation, e
} }
return &u, nil return &u, nil
} }
func (d *ApprovalVacationDao) GetByUsername(username, month string) ([]*model.ApprovalVacation, error) {
var u []*model.ApprovalVacation
tx := GetDB().Table(d.TableName())
tx = tx.Where("month = ?", month)
tx = tx.Where("username = ?", username)
res := tx.Find(&u)
if res.Error != nil {
return nil, res.Error
}
return u, nil
}

View File

@ -65,3 +65,34 @@ func (d *CheckinDao) GetByDay(userId, day string) (*model.Checkin, error) {
} }
return &u, nil return &u, nil
} }
func (d *CheckinDao) CountUsername(month string) ([]*model.UsernameCount, error) {
var userCount []*model.UsernameCount
tx := GetDB().Table(d.TableName())
tx = tx.Where("month = ?", month)
tx.Select("username,COUNT(1) AS count")
tx.Group("username")
tx = tx.Find(&userCount)
if tx.Error != nil {
return nil, tx.Error
}
return userCount, nil
}
func (d *CheckinDao) GetUsernameCount(username, month string, filterException bool) (int64, error) {
tx := GetDB().Table(d.TableName())
tx = tx.Where("month = ?", month)
tx = tx.Where("username = ?", username)
if filterException {
tx = tx.Where("exception = ''")
}
var count int64
tx.Select("COUNT(1) AS count").Pluck("count", &count)
if tx.Error != nil {
return 0, tx.Error
}
return count, nil
}

View File

@ -20,6 +20,11 @@ func (ac *ApprovalCheckin) From(d *qyweixin.ApproveDetail) {
ac.CheckinType = value[2] ac.CheckinType = value[2]
} }
type UsernameCount struct {
Username string `json:"username"`
Count int64 `json:"count"`
}
type ApprovalCheckin struct { type ApprovalCheckin struct {
Id int64 Id int64
Username string Username string

View File

@ -14,6 +14,8 @@ type StaffSalary struct {
AwardSalary float64 AwardSalary float64
SocialInsurence float64 SocialInsurence float64
PersonalTax float64 PersonalTax float64
TotalDay float64
RealDay float64
Holiday float64 Holiday float64
CreateTime int64 CreateTime int64
UpdateTime int64 UpdateTime int64

View File

@ -152,7 +152,7 @@ func (s *StaffSalary) Summary(month string, ctx *gin.Context) {
panic(config.ErrDb.New().Append(err)) panic(config.ErrDb.New().Append(err))
} }
header := []string{"姓名", "身份证号", "入职日期", "转正日期", "基本工资", "出勤工资", "奖金", "社保扣除", "个税扣除", "请假天数", "实发工资"} header := []string{"姓名", "身份证号", "入职日期", "转正日期", "基本工资", "出勤工资", "奖金", "社保扣除", "个税扣除", "应出勤天数", "实际出勤天数", "请假天数", "实发工资"}
datas := make([][]string, 0) datas := make([][]string, 0)
summary := new(model.StaffSalary) summary := new(model.StaffSalary)
for _, staff := range staffSalarys { for _, staff := range staffSalarys {
@ -175,6 +175,8 @@ func (s *StaffSalary) Summary(month string, ctx *gin.Context) {
item = append(item, cast.ToString(staff.AwardSalary)) item = append(item, cast.ToString(staff.AwardSalary))
item = append(item, cast.ToString(staff.SocialInsurence)) item = append(item, cast.ToString(staff.SocialInsurence))
item = append(item, cast.ToString(staff.PersonalTax)) item = append(item, cast.ToString(staff.PersonalTax))
item = append(item, cast.ToString(staff.TotalDay))
item = append(item, cast.ToString(staff.RealDay))
item = append(item, cast.ToString(staff.Holiday)) item = append(item, cast.ToString(staff.Holiday))
item = append(item, cast.ToString(butil.FloatCut(staff.RealSalary+staff.AwardSalary-staff.SocialInsurence-staff.PersonalTax))) item = append(item, cast.ToString(butil.FloatCut(staff.RealSalary+staff.AwardSalary-staff.SocialInsurence-staff.PersonalTax)))

View File

@ -100,29 +100,42 @@ func (s *Staff) SyncStaffSalary(month string) {
month = time.Now().AddDate(0, -1, 0).Format("2006-01") month = time.Now().AddDate(0, -1, 0).Format("2006-01")
} }
month = strings.ReplaceAll(month, "-", "") month = strings.ReplaceAll(month, "-", "")
//cfg := config.GetConfig()
//hrAssiant := weixin.NewQyWeixinHR(cfg.QyWeixin.Corpid, cfg.QyWeixin.HrSecret, cfg.QyWeixin.HrSecret)
staffs, err := dao.NewStaffInfoDao().Query(model.StaffInfoStatusNormal) staffs, err := dao.NewStaffInfoDao().Query(model.StaffInfoStatusNormal)
if err != nil { if err != nil {
log.Errorf("query staff db error :%s", err.Error()) log.Errorf("query staff db error :%s", err.Error())
return return
} }
holidays, err := s.loadHoliday(month)
if err != nil {
log.Errorf("loadHoliday error :%s", err.Error())
return
}
monthTime, _ := time.ParseInLocation("200601", month, time.Local) monthTime, _ := time.ParseInLocation("200601", month, time.Local)
startDate := cast.ToInt(monthTime.Format("20060102")) startDate := cast.ToInt(monthTime.Format("20060102"))
endDate := cast.ToInt(monthTime.AddDate(0, 1, -1).Format("20060102")) endDate := cast.ToInt(monthTime.AddDate(0, 1, -1).Format("20060102"))
salaryDao := dao.NewStaffSalaryDao() salaryDao := dao.NewStaffSalaryDao()
// 计算应出勤天数,选择最大的一个作为应出勤天数
userCounts, err := dao.NewCheckinDao().CountUsername(month)
if err != nil {
log.Errorf("db error :%s", err.Error())
return
}
totalDays := int64(0)
for _, uc := range userCounts {
if uc.Count > totalDays {
totalDays = uc.Count
}
}
for _, staff := range staffs { for _, staff := range staffs {
salary, err := salaryDao.GetBy(staff.Username, month) salary, err := salaryDao.GetBy(staff.Username, month)
if err != nil { if err != nil {
log.Errorf("db error :%s", err.Error()) log.Errorf("db error :%s", err.Error())
continue continue
} }
entryTime, _ := time.ParseInLocation("2006-01-02", staff.EntryDate, time.Local)
officalTime, _ := time.ParseInLocation("2006-01-02", staff.OfficialDate, time.Local)
isEntryMonth := goutil.If(cast.ToInt(entryTime.Format("200601")) == cast.ToInt(month), true, false)
isOfficialMonth := goutil.If(cast.ToInt(officalTime.Format("200601")) == cast.ToInt(month), true, false)
if salary == nil { if salary == nil {
salary = new(model.StaffSalary) salary = new(model.StaffSalary)
salary.Month = month salary.Month = month
@ -133,72 +146,82 @@ func (s *Staff) SyncStaffSalary(month string) {
log.Errorf("db error :%s", err.Error()) log.Errorf("db error :%s", err.Error())
continue continue
} }
// 试用期折扣
discount := cast.ToFloat64(config.Get(model.StaffSalaryExpDiscount)) discount := cast.ToFloat64(config.Get(model.StaffSalaryExpDiscount))
if discount == 0.0 { if discount == 0.0 {
discount = 0.8 discount = 0.8
} }
if cast.ToInt(monthTime.Format("200601")) > cast.ToInt(officalTime.Format("200601")) {
discount = 1.0
}
//社保
socialInsurence := cast.ToFloat64(config.Get(model.StaffSalarySocialInsurence)) socialInsurence := cast.ToFloat64(config.Get(model.StaffSalarySocialInsurence))
if isEntryMonth && entryTime.Day() >= 15 {
socialInsurence = 0
}
approveCheckins, err := dao.NewApprovalCheckinDao().GetByUsername(staff.Username, month)
if err != nil {
log.Errorf("db error :%s", err.Error())
continue
}
checkinCount, err := dao.NewCheckinDao().GetUsernameCount(staff.Username, month, true)
if err != nil {
log.Errorf("db error :%s", err.Error())
continue
}
approveVacations, err := dao.NewApprovalVacationDao().GetByUsername(staff.Username, month)
if err != nil {
log.Errorf("db error :%s", err.Error())
continue
}
holiday := float64(0)
surplusHoliday := float64(0)
for _, vac := range approveVacations {
holiday += vac.VacationDuration
surplusHoliday += goutil.If(vac.VacationDuration <= 1, 1-vac.VacationDuration, 0)
}
extra := make(map[string]interface{}) extra := make(map[string]interface{})
salary.BaseSalary = cast.ToFloat64(staff.Salary) salary.BaseSalary = cast.ToFloat64(staff.Salary)
salary.Holiday = 0 salary.Holiday = holiday
entryDate := cast.ToInt(strings.ReplaceAll(staff.EntryDate, "-", "")) entryDate := cast.ToInt(strings.ReplaceAll(staff.EntryDate, "-", ""))
officialDate := cast.ToInt(strings.ReplaceAll(staff.OfficialDate, "-", "")) officialDate := cast.ToInt(strings.ReplaceAll(staff.OfficialDate, "-", ""))
isEntryMonth := false if discount < 1.0 && isOfficialMonth {
isOfficialMonth := false totalMonthDay := float64(endDate - startDate + 1)
expDays := 0 discount = discount*float64(officialDate-startDate)/totalMonthDay + 1*float64(endDate-officialDate+1)/totalMonthDay
officialDays := 0
if entryDate/100 == startDate/100 {
isEntryMonth = true
}
if officialDate/100 == startDate/100 {
isOfficialMonth = true
}
if entryDate%100 > 15 && isEntryMonth { // 15号以后的员工不缴社保
socialInsurence = 0
} }
if isEntryMonth { realWorkDays := float64(checkinCount+int64(len(approveCheckins))) + surplusHoliday
expDays = endDate - entryDate + 1 realSalary := salary.BaseSalary * (realWorkDays / float64(totalDays)) * discount
officialDays = 0
} else if isOfficialMonth {
expDays = officialDate - startDate + 1
officialDays = endDate - officialDate
} else if endDate < officialDate {
expDays = endDate - startDate + 1
officialDays = 0
} else {
officialDays = endDate - startDate + 1
expDays = 0
}
holiday := butil.FloatCut(holidays[staff.Username])
expSalary := cast.ToFloat64(staff.Salary) * discount / float64(endDate-startDate+1)
officalSalary := cast.ToFloat64(staff.Salary) / float64(endDate-startDate+1)
realSalary := expSalary*float64(expDays) + officalSalary*float64(officialDays) - holiday*officalSalary
extra["discount"] = discount extra["discount"] = discount
extra["socialInsurence"] = socialInsurence extra["socialInsurence"] = socialInsurence
extra["expDays"] = expDays
extra["officialDays"] = officialDays
extra["expSalary"] = butil.FloatCut(expSalary)
extra["officalSalary"] = butil.FloatCut(officalSalary)
extra["days"] = endDate - startDate + 1 extra["days"] = endDate - startDate + 1
extra["realDays"] = expDays + officialDays extra["startDate"] = startDate
extra["totalDays"] = totalDays
extra["realDays"] = realWorkDays
extra["startDate"] = startDate extra["startDate"] = startDate
extra["endDate"] = endDate extra["endDate"] = endDate
extra["officialDate"] = officialDate extra["officialDate"] = officialDate
extra["entryDate"] = entryDate extra["entryDate"] = entryDate
extra["isEntryMonth"] = isEntryMonth extra["isEntryMonth"] = isEntryMonth
extra["isOfficialMonth"] = isOfficialMonth extra["isOfficialMonth"] = isOfficialMonth
extra["surplusHoliday"] = surplusHoliday
salary.RealSalary = butil.FloatCut(realSalary) salary.RealSalary = butil.FloatCut(realSalary)
salary.SocialInsurence = socialInsurence salary.SocialInsurence = socialInsurence
salary.Holiday = holiday salary.Holiday = holiday
salary.TotalDay = float64(totalDays)
salary.RealDay = realWorkDays
salary.Extra = goutil.EncodeJSONIndent(extra) salary.Extra = goutil.EncodeJSONIndent(extra)
if salary.Id == 0 { if salary.Id == 0 {
_, err = dao.NewStaffSalaryDao().Create(salary) _, err = dao.NewStaffSalaryDao().Create(salary)
@ -211,37 +234,3 @@ func (s *Staff) SyncStaffSalary(month string) {
} }
} }
func (s *Staff) loadHoliday(month string) (map[string]float64, error) {
cfg := config.GetConfig()
approve := qyweixin.NewAppApprove(&qyweixin.AppConfig{
Corpid: cfg.QyWeixin.Corpid,
Secret: cfg.QyWeixin.ApproveSecret,
Agent: cfg.QyWeixin.ApproveAgent,
})
startTime, _ := time.ParseInLocation("200601", month, time.Local)
endTime := startTime.AddDate(0, 1, 0)
spNos, err := approve.GetList(startTime.Unix(), endTime.Unix()-1, "3WLJF6naF5jhnXvwisuPmE85wVMYcy1S1ZvYibkw")
if err != nil {
log.Errorf("approve getlist error :%s", err.Error())
return nil, err
}
result := make(map[string]float64)
for _, spNo := range spNos {
detail, err := approve.GetDetail(spNo)
if err != nil {
log.Errorf("approve GetDetail error :%s", err.Error())
return nil, err
}
userId := detail.GetUserid()
holidayType := detail.GetValue("请假类型")
fields := strings.SplitN(holidayType, ",", 4)
hours := float64(cast.ToInt64(fields[3])) / float64(3600*8)
if v, ok := result[userId]; ok {
result[userId] = v + hours
} else {
result[userId] = hours
}
}
return result, nil
}