From b6e5112bb67b2d884eea524ec25afb9bbc43a92e Mon Sep 17 00:00:00 2001 From: jiangyong27 Date: Fri, 1 Sep 2023 20:01:30 +0800 Subject: [PATCH] hr assiant3 --- base/util/util.go | 6 ++ common/dao/staff_salary.go | 85 ++++++++++++++++++++++++++ common/model/staff_info.go | 1 + common/model/staff_salary.go | 14 +++++ common/model/user_config.go | 10 ++-- common/weixin/qyweixin_hr.go | 2 + worker/staff.go | 112 ++++++++++++++++++++++++++++++++++- 7 files changed, 225 insertions(+), 5 deletions(-) create mode 100644 common/dao/staff_salary.go create mode 100644 common/model/staff_salary.go diff --git a/base/util/util.go b/base/util/util.go index af3fa8c..fdfa6c1 100644 --- a/base/util/util.go +++ b/base/util/util.go @@ -1,6 +1,8 @@ package util import ( + "fmt" + "github.com/spf13/cast" "math/rand" "time" ) @@ -23,3 +25,7 @@ func CutTail(str string, length int) string { return str[0:length] } + +func FloatCut(f float64) float64 { + return cast.ToFloat64(fmt.Sprintf("%.2f", f)) +} diff --git a/common/dao/staff_salary.go b/common/dao/staff_salary.go new file mode 100644 index 0000000..9b36e68 --- /dev/null +++ b/common/dao/staff_salary.go @@ -0,0 +1,85 @@ +package dao + +import ( + "enterprise/common/model" + "gorm.io/gorm" + "time" +) + +type StaffSalaryDao struct { +} + +func NewStaffSalaryDao() *StaffSalaryDao { + return &StaffSalaryDao{} +} + +func (d *StaffSalaryDao) TableName() string { + return "staff_salary" +} + +func (d *StaffSalaryDao) Create(o *model.StaffSalary) (int64, error) { + o.CreateTime = time.Now().Unix() + res := GetDB().Table(d.TableName()).Create(o) + return o.Id, res.Error +} + +func (d *StaffSalaryDao) Update(o *model.StaffSalary) error { + o.UpdateTime = time.Now().Unix() + tx := GetDB().Table(d.TableName()) + res := tx.Save(o) + return res.Error +} + +func (d *StaffSalaryDao) Delete(id int64) error { + res := GetDB().Table(d.TableName()).Delete(&model.StaffSalary{}, id) + return res.Error +} + +func (d *StaffSalaryDao) Get(id int64) (*model.StaffSalary, error) { + var u model.StaffSalary + tx := GetDB().Table(d.TableName()) + tx = tx.Where("id = ?", id) + res := tx.First(&u) + if res.Error == gorm.ErrRecordNotFound { + return nil, nil + } + + if res.Error != nil { + return nil, res.Error + } + return &u, nil +} + +func (d *StaffSalaryDao) GetBy(username, month string) (*model.StaffSalary, error) { + var u model.StaffSalary + tx := GetDB().Table(d.TableName()) + tx = tx.Where("username = ?", username) + tx = tx.Where("month = ?", month) + res := tx.First(&u) + if res.Error == gorm.ErrRecordNotFound { + return nil, nil + } + + if res.Error != nil { + return nil, res.Error + } + return &u, nil +} + +func (d *StaffSalaryDao) Query(status int) ([]*model.StaffSalary, error) { + var u []*model.StaffSalary + tx := GetDB().Table(d.TableName()) + if status != 0 { + tx = tx.Where("status = ?", status) + } + + res := tx.Find(&u) + if res.Error == gorm.ErrRecordNotFound { + return nil, nil + } + + if res.Error != nil { + return nil, res.Error + } + return u, nil +} diff --git a/common/model/staff_info.go b/common/model/staff_info.go index 985d796..0727b7c 100644 --- a/common/model/staff_info.go +++ b/common/model/staff_info.go @@ -9,6 +9,7 @@ type StaffInfo struct { Id int64 Username string Realname string + StaffType string Phone string Idno string Salary string diff --git a/common/model/staff_salary.go b/common/model/staff_salary.go new file mode 100644 index 0000000..bb32df7 --- /dev/null +++ b/common/model/staff_salary.go @@ -0,0 +1,14 @@ +package model + +type StaffSalary struct { + Id int64 + Username string + Month string + BaseSalary float64 + RealSalary float64 + SocialInsurence float64 + Holiday int + CreateTime int64 + UpdateTime int64 + Extra string +} diff --git a/common/model/user_config.go b/common/model/user_config.go index f5b6776..715c3e5 100644 --- a/common/model/user_config.go +++ b/common/model/user_config.go @@ -3,10 +3,12 @@ package model import "encoding/json" var ( - CheckinOndutyMoneyEnable = "checkin.onduty.money.enable" - CheckinOffdutyMoneyEnable = "checkin.offduty.money.enable" - CheckinOndutyMoney = "checkin.onduty.money" - CheckinOffdutyMoney = "checkin.offduty.money" + CheckinOndutyMoneyEnable = "checkin.onduty.money.enable" //上班打卡红包 + CheckinOffdutyMoneyEnable = "checkin.offduty.money.enable" //下班打卡红包 + CheckinOndutyMoney = "checkin.onduty.money" //上班打卡金额 + CheckinOffdutyMoney = "checkin.offduty.money" //下班打卡金额 + StaffSalaryExpDiscount = "staff.salary.exp.discount" //试用期薪资折扣 + StaffSalarySocialInsurence = "staff.salary.social.insurence" //社保扣除金额 ) var ( UserConfigStatusNormal = 1 diff --git a/common/weixin/qyweixin_hr.go b/common/weixin/qyweixin_hr.go index 357aa5e..9622252 100644 --- a/common/weixin/qyweixin_hr.go +++ b/common/weixin/qyweixin_hr.go @@ -22,6 +22,7 @@ type StaffInfo struct { UserName string RealName string Phone string + StaffType string Idno string Salary float64 Stock float64 @@ -73,6 +74,7 @@ func (h *QyWeixinHR) GetStaffInfo(userId string) (*StaffInfo, error) { staff.Salary = cast.ToFloat64(h.getFieldValue(fieldMap["20001"])) staff.Stock = cast.ToFloat64(h.getFieldValue(fieldMap["20002"])) staff.Phone = cast.ToString(h.getFieldValue(fieldMap["17003"])) + staff.StaffType = cast.ToString(h.getFieldValue(fieldMap["12003"])) staff.Idno = cast.ToString(h.getFieldValue(fieldMap["11015"])) staff.BankName = cast.ToString(h.getFieldValue(fieldMap["13001"])) staff.BankCard = cast.ToString(h.getFieldValue(fieldMap["13002"])) diff --git a/worker/staff.go b/worker/staff.go index 2c93575..cf38b28 100644 --- a/worker/staff.go +++ b/worker/staff.go @@ -1,12 +1,16 @@ package worker import ( + butil "enterprise/base/util" "enterprise/common/config" "enterprise/common/dao" "enterprise/common/model" "enterprise/common/weixin" log "github.com/sirupsen/logrus" + "github.com/smbrave/goutil" "github.com/spf13/cast" + "strings" + "time" ) func SyncStaffInfo() { @@ -34,8 +38,8 @@ func SyncStaffInfo() { } staff.Username = staffInfo.UserName staff.Realname = staffInfo.RealName - staff.Phone = staffInfo.Phone staff.Idno = staffInfo.Idno + staff.StaffType = staffInfo.StaffType staff.Salary = cast.ToString(staffInfo.Salary) staff.EntryDate = staffInfo.EntryDate staff.OfficialDate = staffInfo.OfficialDate @@ -54,3 +58,109 @@ func SyncStaffInfo() { } } } + +func CalcStaffSalary(month string) { + //cfg := config.GetConfig() + //hrAssiant := weixin.NewQyWeixinHR(cfg.QyWeixin.Corpid, cfg.QyWeixin.HrSecret, cfg.QyWeixin.HrSecret) + + staffs, err := dao.NewStaffInfoDao().Query(model.StaffInfoStatusNormal) + if err != nil { + log.Errorf("query staff db error :%s", err.Error()) + return + } + month = strings.ReplaceAll(month, "-", "") + monthTime, _ := time.ParseInLocation("200601", month, time.Local) + startDate := cast.ToInt(monthTime.Format("20060102")) + endDate := cast.ToInt(monthTime.AddDate(0, 1, -1).Format("20060102")) + salaryDao := dao.NewStaffSalaryDao() + for _, staff := range staffs { + salary, err := salaryDao.GetBy(staff.Username, month) + if err != nil { + log.Errorf("db error :%s", err.Error()) + continue + } + if salary == nil { + salary = new(model.StaffSalary) + salary.Month = month + salary.Username = staff.Username + } + config, err := dao.NewUserConfigDao().GetByUsername(staff.Username) + if err != nil { + log.Errorf("db error :%s", err.Error()) + continue + } + discount := cast.ToFloat64(config.Get(model.StaffSalaryExpDiscount)) + if discount == 0.0 { + discount = 0.8 + } + socialInsurence := cast.ToFloat64(config.Get(model.StaffSalarySocialInsurence)) + if endDate%100 > 15 { // 15号以后的员工不缴社保 + socialInsurence = 0 + } + extra := make(map[string]interface{}) + + salary.BaseSalary = cast.ToFloat64(staff.Salary) + salary.Holiday = 0 + + entryDate := cast.ToInt(strings.ReplaceAll(staff.EntryDate, "-", "")) + officialDate := cast.ToInt(strings.ReplaceAll(staff.OfficialDate, "-", "")) + + isEntryMonth := false + isOfficialMonth := false + expDays := 0 + officialDays := 0 + + if entryDate/100 == startDate/100 { + isEntryMonth = true + } + if officialDate/100 == startDate/100 { + isOfficialMonth = true + } + + if isEntryMonth { + expDays = endDate - entryDate + 1 + 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 + } + + 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) - socialInsurence + + extra["discount"] = discount + 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["realDays"] = expDays + officialDays + extra["startDate"] = startDate + extra["endDate"] = endDate + extra["officialDate"] = officialDate + extra["entryDate"] = entryDate + extra["isEntryMonth"] = isEntryMonth + extra["isOfficialMonth"] = isOfficialMonth + + salary.RealSalary = butil.FloatCut(realSalary) + salary.SocialInsurence = socialInsurence + salary.Extra = goutil.EncodeJSONIndent(extra) + if salary.Id == 0 { + _, err = dao.NewStaffSalaryDao().Create(salary) + } else { + err = dao.NewStaffSalaryDao().Update(salary) + } + if err != nil { + log.Errorf("db error :%s", err.Error()) + } + } + +}