1132 lines
39 KiB
Go
1132 lines
39 KiB
Go
|
package service
|
||
|
|
||
|
import (
|
||
|
"context"
|
||
|
"errors"
|
||
|
"fmt"
|
||
|
"github.com/fonchain_enterprise/fonchain-main/api/account"
|
||
|
"github.com/fonchain_enterprise/fonchain-main/api/oa"
|
||
|
"github.com/fonchain_enterprise/fonchain-main/api/rule"
|
||
|
"github.com/fonchain_enterprise/fonchain-main/pkg/e"
|
||
|
"github.com/fonchain_enterprise/fonchain-main/pkg/model/login"
|
||
|
"github.com/fonchain_enterprise/fonchain-main/pkg/model/oa_model"
|
||
|
"github.com/fonchain_enterprise/fonchain-main/pkg/service/oa_new/common"
|
||
|
"github.com/fonchain_enterprise/fonchain-main/pkg/utils/holiday"
|
||
|
"github.com/gin-gonic/gin"
|
||
|
"github.com/jinzhu/copier"
|
||
|
"math"
|
||
|
"strconv"
|
||
|
"strings"
|
||
|
"time"
|
||
|
)
|
||
|
|
||
|
// WorkingTimeBest
|
||
|
// 生成 最优 考勤班次 针对 特殊员工
|
||
|
func WorkingTimeBest(staffUID uint64, in []oa_model.QueryTimeOption) (bestOptions []*oa_model.TimeOption, err error) {
|
||
|
/*
|
||
|
多个部门 组合 最优 考勤班次
|
||
|
|
||
|
9:00 17:00 10:00 18:00
|
||
|
=> 10:00 17:00
|
||
|
*/
|
||
|
|
||
|
if in == nil {
|
||
|
in = make([]oa_model.QueryTimeOption, 0)
|
||
|
in, err = MakeQueryTimeOption(staffUID)
|
||
|
if err != nil {
|
||
|
return bestOptions, err
|
||
|
}
|
||
|
}
|
||
|
|
||
|
timesMap := make(map[int][]*oa_model.TimeOption, 0)
|
||
|
for i := 0; i < len(in); i++ {
|
||
|
res, _, _ := WorkingTimeSetting(in[i])
|
||
|
|
||
|
// 如果 考勤规则 为 空 则跳过
|
||
|
if len(res) == 0 {
|
||
|
continue
|
||
|
}
|
||
|
|
||
|
/* 比较 打卡次数 一致的 班次规则 */
|
||
|
|
||
|
v, isExist := timesMap[len(res)]
|
||
|
if isExist {
|
||
|
/* 打卡 次数 一致
|
||
|
判断 时间点 先后
|
||
|
宗旨 上班晚 下班早
|
||
|
*/
|
||
|
for i := 0; i < len(v); i++ {
|
||
|
oldOnWorkTime := "2006-01-02 " + v[i].OnWorkTime + ":00"
|
||
|
newOnWorkTime := "2006-01-02 " + res[i].OnWorkTime + ":00"
|
||
|
oldOnWorkTimeF, err := time.ParseInLocation("2006-01-02 15:04:05", oldOnWorkTime, time.Local)
|
||
|
newOnWorkTimeF, err := time.ParseInLocation("2006-01-02 15:04:05", newOnWorkTime, time.Local)
|
||
|
if err == nil && newOnWorkTimeF.After(oldOnWorkTimeF) {
|
||
|
v[i].OnWorkTime = res[i].OnWorkTime
|
||
|
}
|
||
|
|
||
|
oldOffWorkTime := "2006-01-02 " + v[i].OffWorkTime + ":00"
|
||
|
newOffWorkTime := "2006-01-02 " + res[i].OffWorkTime + ":00"
|
||
|
oldOffWorkTimeF, err := time.ParseInLocation("2006-01-02 15:04:05", oldOffWorkTime, time.Local)
|
||
|
newOffWorkTimeF, err := time.ParseInLocation("2006-01-02 15:04:05", newOffWorkTime, time.Local)
|
||
|
if err == nil && newOffWorkTimeF.Before(oldOffWorkTimeF) {
|
||
|
v[i].OffWorkTime = res[i].OffWorkTime
|
||
|
}
|
||
|
}
|
||
|
|
||
|
} else {
|
||
|
timesMap[len(res)] = res
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// 至此 已筛选出 每一类 打卡次数 的 最优 时间
|
||
|
bestOptions = make([]*oa_model.TimeOption, 0)
|
||
|
|
||
|
if len(timesMap) == 1 {
|
||
|
for _, v := range timesMap {
|
||
|
bestOptions = v
|
||
|
}
|
||
|
return bestOptions, nil
|
||
|
}
|
||
|
|
||
|
// 判断 是否存在 两次 打卡
|
||
|
// 默认 两次 打卡 为 最优打卡次数 其次 四次 以此类推
|
||
|
|
||
|
currentBestClockInNum := 9999
|
||
|
|
||
|
for k, v := range timesMap {
|
||
|
|
||
|
if currentBestClockInNum > k {
|
||
|
currentBestClockInNum = k
|
||
|
bestOptions = v
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// 当前 默认 只有 两次 或者 四次
|
||
|
// 注: 超过 四次 不适用
|
||
|
for k, v := range timesMap {
|
||
|
|
||
|
if k == currentBestClockInNum {
|
||
|
continue
|
||
|
}
|
||
|
|
||
|
for i := 0; i < k; {
|
||
|
|
||
|
oldOnWorkTime := "2006-01-02 " + bestOptions[i].OnWorkTime + ":00"
|
||
|
newOnWorkTime := "2006-01-02 " + v[i].OnWorkTime + ":00"
|
||
|
oldOnWorkTimeF, err := time.ParseInLocation("2006-01-02 15:04:05", oldOnWorkTime, time.Local)
|
||
|
newOnWorkTimeF, err := time.ParseInLocation("2006-01-02 15:04:05", newOnWorkTime, time.Local)
|
||
|
if err == nil && newOnWorkTimeF.After(oldOnWorkTimeF) {
|
||
|
bestOptions[i].OnWorkTime = v[i].OnWorkTime
|
||
|
}
|
||
|
|
||
|
oldOffWorkTime := "2006-01-02 " + bestOptions[i].OffWorkTime + ":00"
|
||
|
newOffWorkTime := "2006-01-02 " + v[i+1].OffWorkTime + ":00"
|
||
|
oldOffWorkTimeF, err := time.ParseInLocation("2006-01-02 15:04:05", oldOffWorkTime, time.Local)
|
||
|
newOffWorkTimeF, err := time.ParseInLocation("2006-01-02 15:04:05", newOffWorkTime, time.Local)
|
||
|
if err == nil && newOffWorkTimeF.Before(oldOffWorkTimeF) {
|
||
|
bestOptions[i].OffWorkTime = v[i+1].OffWorkTime
|
||
|
}
|
||
|
|
||
|
i = k
|
||
|
}
|
||
|
}
|
||
|
|
||
|
for i := 0; i < len(bestOptions); i++ {
|
||
|
|
||
|
fmt.Printf("%+v\n", bestOptions[i])
|
||
|
}
|
||
|
|
||
|
return bestOptions, nil
|
||
|
}
|
||
|
|
||
|
// WorkingTimeBestV1
|
||
|
// 生成 最优 考勤班次 针对 特殊员工
|
||
|
func WorkingTimeBestV1(c *gin.Context, in []oa_model.QueryTimeOption) (times []*oa_model.TimeOption, err error) {
|
||
|
/*
|
||
|
多个部门 组合 最优 考勤班次
|
||
|
|
||
|
9:00 17:00 10:00 18:00
|
||
|
=> 10:00 17:00
|
||
|
*/
|
||
|
|
||
|
timesMap := make(map[int][]*oa_model.TimeOption, 0)
|
||
|
for i := 0; i < len(in); i++ {
|
||
|
res, _, err := WorkingTimeSetting(in[i])
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
|
||
|
/* 比较 打卡次数 一致的 班次规则 */
|
||
|
|
||
|
v, isExist := timesMap[len(res)]
|
||
|
if isExist {
|
||
|
/* 打卡 次数 一致
|
||
|
判断 时间点 先后
|
||
|
宗旨 上班晚 下班早
|
||
|
*/
|
||
|
for i := 0; i < len(v); i++ {
|
||
|
oldOnWorkTime := "2006-01-02 " + v[i].OnWorkTime + ":00"
|
||
|
newOnWorkTime := "2006-01-02 " + res[i].OnWorkTime + ":00"
|
||
|
oldOnWorkTimeF, err := time.ParseInLocation("2006-01-02 15:04:05", oldOnWorkTime, time.Local)
|
||
|
newOnWorkTimeF, err := time.ParseInLocation("2006-01-02 15:04:05", newOnWorkTime, time.Local)
|
||
|
if err == nil && newOnWorkTimeF.After(oldOnWorkTimeF) {
|
||
|
v[i].OnWorkTime = res[i].OnWorkTime
|
||
|
}
|
||
|
|
||
|
oldOffWorkTime := "2006-01-02 " + v[i].OffWorkTime + ":00"
|
||
|
newOffWorkTime := "2006-01-02 " + res[i].OffWorkTime + ":00"
|
||
|
oldOffWorkTimeF, err := time.ParseInLocation("2006-01-02 15:04:05", oldOffWorkTime, time.Local)
|
||
|
newOffWorkTimeF, err := time.ParseInLocation("2006-01-02 15:04:05", newOffWorkTime, time.Local)
|
||
|
if err == nil && newOffWorkTimeF.Before(oldOffWorkTimeF) {
|
||
|
v[i].OffWorkTime = res[i].OffWorkTime
|
||
|
}
|
||
|
}
|
||
|
|
||
|
} else {
|
||
|
timesMap[len(res)] = res
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// 至此 已筛选出 每一类 打卡次数 的 最优 时间
|
||
|
bestOptions := make([]*oa_model.TimeOption, 0)
|
||
|
|
||
|
if len(timesMap) == 1 {
|
||
|
for _, v := range timesMap {
|
||
|
bestOptions = v
|
||
|
}
|
||
|
return bestOptions, nil
|
||
|
}
|
||
|
|
||
|
// 判断 是否存在 两次 打卡
|
||
|
// 默认 两次 打卡 为 最优打卡次数 其次 四次 以此类推
|
||
|
currentBestClockInNum := 9999
|
||
|
|
||
|
for k, v := range timesMap {
|
||
|
|
||
|
if currentBestClockInNum > k {
|
||
|
currentBestClockInNum = k
|
||
|
bestOptions = v
|
||
|
}
|
||
|
}
|
||
|
|
||
|
for k, v := range timesMap {
|
||
|
bestClockInIndex := 0
|
||
|
bestOnWorkTimeIsChange := false
|
||
|
for i := 0; i < k; {
|
||
|
|
||
|
if bestClockInIndex > currentBestClockInNum {
|
||
|
return
|
||
|
}
|
||
|
|
||
|
if !bestOnWorkTimeIsChange {
|
||
|
oldOnWorkTime := "2006-01-02 " + bestOptions[bestClockInIndex].OnWorkTime + ":00"
|
||
|
newOnWorkTime := "2006-01-02 " + v[i].OnWorkTime + ":00"
|
||
|
oldOnWorkTimeF, err := time.ParseInLocation("2006-01-02 15:04:05", oldOnWorkTime, time.Local)
|
||
|
newOnWorkTimeF, err := time.ParseInLocation("2006-01-02 15:04:05", newOnWorkTime, time.Local)
|
||
|
if err == nil && newOnWorkTimeF.After(oldOnWorkTimeF) {
|
||
|
bestOptions[bestClockInIndex].OnWorkTime = v[i].OnWorkTime
|
||
|
bestOnWorkTimeIsChange = true
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if k > currentBestClockInNum {
|
||
|
i++
|
||
|
continue
|
||
|
}
|
||
|
|
||
|
oldOffWorkTime := "2006-01-02 " + bestOptions[bestClockInIndex].OffWorkTime + ":00"
|
||
|
newOffWorkTime := "2006-01-02 " + v[i].OffWorkTime + ":00"
|
||
|
oldOffWorkTimeF, err := time.ParseInLocation("2006-01-02 15:04:05", oldOffWorkTime, time.Local)
|
||
|
newOffWorkTimeF, err := time.ParseInLocation("2006-01-02 15:04:05", newOffWorkTime, time.Local)
|
||
|
if err == nil && newOffWorkTimeF.Before(oldOffWorkTimeF) {
|
||
|
bestOptions[bestClockInIndex].OffWorkTime = v[i].OffWorkTime
|
||
|
}
|
||
|
|
||
|
bestClockInIndex++
|
||
|
|
||
|
}
|
||
|
|
||
|
//if isBestOnWorkTime == "" {
|
||
|
// isBestOnWorkTime = currentOnWorkTime
|
||
|
//} else {
|
||
|
// oldOnWorkTime := "2006-01-02 " + isBestOnWorkTime + ":00"
|
||
|
// newOnWorkTime := "2006-01-02 " + currentOnWorkTime + ":00"
|
||
|
// oldOnWorkTimeF, err := time.ParseInLocation("2006-01-02 15:04:05", oldOnWorkTime, time.Local)
|
||
|
// newOnWorkTimeF, err := time.ParseInLocation("2006-01-02 15:04:05", newOnWorkTime, time.Local)
|
||
|
// if err == nil && newOnWorkTimeF.After(oldOnWorkTimeF) {
|
||
|
// isBestOnWorkTime = currentOnWorkTime
|
||
|
// }
|
||
|
//}
|
||
|
//
|
||
|
//if isBestOffWorkTime == "" {
|
||
|
// isBestOffWorkTime = currentOffWorkTime
|
||
|
//} else {
|
||
|
// oldOffWorkTime := "2006-01-02 " + isBestOffWorkTime + ":00"
|
||
|
// newOffWorkTime := "2006-01-02 " + currentOffWorkTime + ":00"
|
||
|
// oldOffWorkTimeF, err := time.ParseInLocation("2006-01-02 15:04:05", oldOffWorkTime, time.Local)
|
||
|
// newOffWorkTimeF, err := time.ParseInLocation("2006-01-02 15:04:05", newOffWorkTime, time.Local)
|
||
|
// if err == nil && newOffWorkTimeF.Before(oldOffWorkTimeF) {
|
||
|
// isBestOffWorkTime = currentOffWorkTime
|
||
|
// }
|
||
|
//}
|
||
|
}
|
||
|
|
||
|
//currentClockInNum := 0
|
||
|
//currentClockInRule := make([]*oaApi.TimeOption, 0)
|
||
|
//for i, options := range timesMap {
|
||
|
// if currentClockInNum == 0 {
|
||
|
// currentClockInNum = i
|
||
|
// currentClockInRule = options
|
||
|
// }
|
||
|
// if i < currentClockInNum {
|
||
|
// currentClockInNum = i
|
||
|
// currentClockInRule = options
|
||
|
// }
|
||
|
//}
|
||
|
|
||
|
return bestOptions, nil
|
||
|
}
|
||
|
|
||
|
// WorkingTimeSetting
|
||
|
// 获取 考勤班次设置
|
||
|
func WorkingTimeSetting(in oa_model.QueryTimeOption) (times []*oa_model.TimeOption, week string, err error) {
|
||
|
timeOptions := new(oa.WorkingTimeListReq)
|
||
|
timeOptions.DepartmentUID = in.DepartmentUID
|
||
|
timeOptions.PositionUID = in.PositionUID
|
||
|
timeOptions.InUse = oa_model.InUse
|
||
|
timeOptions.Page = 1
|
||
|
timeOptions.PageSize = 9999
|
||
|
|
||
|
list, err := GrpcOAImpl.WorkingTimeList(context.Background(), timeOptions)
|
||
|
if err != nil {
|
||
|
return nil, "", nil
|
||
|
}
|
||
|
|
||
|
fmt.Println("WorkingTimeSetting department uid is = ==============================================")
|
||
|
fmt.Println("department uid is :", timeOptions.DepartmentUID)
|
||
|
fmt.Println("position uid is :", timeOptions.PositionUID)
|
||
|
fmt.Println("WorkingTimeSetting department uid is = ==============================================")
|
||
|
|
||
|
fmt.Println("WorkingTimeSetting timeOptions is = ==============================================")
|
||
|
fmt.Printf("WorkingTimeSetting timeOptions is :%+v\n", list.Data)
|
||
|
fmt.Println("WorkingTimeSetting timeOptions is = ==============================================")
|
||
|
|
||
|
times = make([]*oa_model.TimeOption, 0)
|
||
|
for i := 0; i < len(list.Data); i++ {
|
||
|
for j := 0; j < len(list.Data[i].Time); j++ {
|
||
|
times = append(times, &oa_model.TimeOption{
|
||
|
OnWorkTime: list.Data[i].Time[j].OnWorkTime,
|
||
|
OffWorkTime: list.Data[i].Time[j].OffWorkTime,
|
||
|
})
|
||
|
}
|
||
|
week = list.Data[i].Week
|
||
|
}
|
||
|
return times, week, nil
|
||
|
}
|
||
|
|
||
|
func WorkingTimeWeek(in oa_model.QueryTimeOption) (list *oa.WorkingTimeListRes, err error) {
|
||
|
|
||
|
timeOptions := new(oa.WorkingTimeListReq)
|
||
|
timeOptions.DepartmentUID = in.DepartmentUID
|
||
|
timeOptions.PositionUID = in.PositionUID
|
||
|
timeOptions.InUse = oa_model.InUse
|
||
|
timeOptions.Page = 1
|
||
|
timeOptions.PageSize = 9999
|
||
|
|
||
|
list, err = GrpcOAImpl.WorkingTimeList(context.Background(), timeOptions)
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
|
||
|
fmt.Println("WorkingTimeWeek department uid is = ==============================================")
|
||
|
fmt.Println("department uid is :", timeOptions.DepartmentUID)
|
||
|
fmt.Println("position uid is :", timeOptions.PositionUID)
|
||
|
fmt.Println("WorkingTimeWeek department uid is = ==============================================")
|
||
|
|
||
|
fmt.Println("WorkingTimeWeek timeOptions is = ==============================================")
|
||
|
fmt.Printf("WorkingTimeWeek timeOptions is :%+v\n", list.Data)
|
||
|
fmt.Println("WorkingTimeWeek timeOptions is = ==============================================")
|
||
|
return
|
||
|
}
|
||
|
|
||
|
// 获取 工作周期 ( 如果 开始周期 是 0 则不变 结束周期 是 0 则将 0 -> 7 )
|
||
|
func WorkingTimeWeekBest(queryTimeOptions []oa_model.QueryTimeOption) (startDay, endDay int, err error) {
|
||
|
|
||
|
startDay, endDay = -1, -1
|
||
|
for i := 0; i < len(queryTimeOptions); i++ {
|
||
|
list, err := WorkingTimeWeek(queryTimeOptions[i])
|
||
|
if err != nil {
|
||
|
return 0, 0, errors.New(e.ErrConfirmweek)
|
||
|
}
|
||
|
if len(list.Data) == 0 {
|
||
|
continue
|
||
|
}
|
||
|
inStartDay, inEndDay := -1, -1
|
||
|
for j := 0; j < len(list.Data); j++ {
|
||
|
fmt.Println("===================== 打印 数据库 week ===================================")
|
||
|
fmt.Printf("week info is : %+v\n", list.Data[j].Week)
|
||
|
fmt.Printf("week info is : %+v\n", list.Data[j].IsWorkDay)
|
||
|
fmt.Println("===================== 打印 数据库 week ===================================")
|
||
|
if list.Data[j].Week == "" && list.Data[j].IsWorkDay == e.IsWorkDay {
|
||
|
list.Data[j].Week = "1,5"
|
||
|
}
|
||
|
weekStr := strings.Split(list.Data[j].Week, ",")
|
||
|
if len(weekStr) != 2 {
|
||
|
return 0, 0, errors.New("考勤规则,week错误")
|
||
|
}
|
||
|
inInStartDay, err := strconv.Atoi(weekStr[0])
|
||
|
if err != nil {
|
||
|
return 0, 0, err
|
||
|
}
|
||
|
inInEndDay, err := strconv.Atoi(weekStr[1])
|
||
|
if err != nil {
|
||
|
return 0, 0, err
|
||
|
}
|
||
|
// 特别注意的点 起始位是 0 无需关注
|
||
|
if inInEndDay == 0 {
|
||
|
inInEndDay = 7
|
||
|
}
|
||
|
if j == 0 {
|
||
|
inStartDay = inInStartDay
|
||
|
inEndDay = inInEndDay
|
||
|
} else {
|
||
|
if inInStartDay >= inStartDay {
|
||
|
inStartDay = inInStartDay
|
||
|
}
|
||
|
if inInEndDay <= inEndDay {
|
||
|
inEndDay = inInEndDay
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if inStartDay >= startDay {
|
||
|
startDay = inStartDay
|
||
|
}
|
||
|
if endDay == -1 {
|
||
|
endDay = inEndDay
|
||
|
}
|
||
|
if inEndDay <= endDay {
|
||
|
endDay = inEndDay
|
||
|
}
|
||
|
}
|
||
|
return
|
||
|
}
|
||
|
|
||
|
func WorkingTimeInWeek(currentDay, startDay, endDay int) bool {
|
||
|
if startDay <= currentDay && currentDay <= endDay {
|
||
|
return true
|
||
|
}
|
||
|
return false
|
||
|
}
|
||
|
|
||
|
func MakeQueryTimeOption(staffUID uint64) (option []oa_model.QueryTimeOption, err error) {
|
||
|
rulesRequest := new(rule.RulesRequest)
|
||
|
rulesRequest.AccountID = staffUID
|
||
|
rulesRes, err := RuleProvider.UserInfo(context.Background(), rulesRequest)
|
||
|
if err != nil {
|
||
|
//logger.Error("查询岗位信息错误 ListByDid err", err)
|
||
|
return option, err
|
||
|
}
|
||
|
|
||
|
for i := 0; i < len(rulesRes.PositionUsers); i++ {
|
||
|
option = append(option, oa_model.QueryTimeOption{
|
||
|
PositionUID: strconv.FormatUint(rulesRes.PositionUsers[i].PositionID, 10),
|
||
|
DepartmentUID: strconv.FormatUint(rulesRes.PositionUsers[i].DepartmentId, 10),
|
||
|
})
|
||
|
}
|
||
|
return
|
||
|
}
|
||
|
|
||
|
func HandleHourLeaveFive(originHour float64) float32 {
|
||
|
var hour float64
|
||
|
hour = math.Floor(originHour / 1)
|
||
|
if math.Mod(originHour, 1) >= 0.5 {
|
||
|
hour = hour + 0.5
|
||
|
}
|
||
|
return float32(hour)
|
||
|
}
|
||
|
|
||
|
func HandleHourLeaveASeat(originHour float64) float32 {
|
||
|
var hour float64
|
||
|
if originHour > 0 && originHour < 0.1 {
|
||
|
hour = 0.1
|
||
|
} else {
|
||
|
//hour, _ = strconv.ParseFloat(strconv.FormatFloat(originHour-0.05, 'f', 1, 64), 10)
|
||
|
hour, _ = strconv.ParseFloat(strconv.FormatFloat(originHour, 'f', 1, 64), 10)
|
||
|
}
|
||
|
return float32(hour)
|
||
|
}
|
||
|
|
||
|
func WorkingTimeAndWeekBest(staffUID uint64, in []oa_model.QueryTimeOption) (best *oa_model.TimeOptionBest, err error) {
|
||
|
times, err := WorkingTimeBest(0, in)
|
||
|
if err != nil {
|
||
|
return best, err
|
||
|
}
|
||
|
|
||
|
fmt.Println("timeOptions is = ==============================================")
|
||
|
fmt.Printf("timeOptions is :%+v\n", times)
|
||
|
fmt.Println("timeOptions is = ==============================================")
|
||
|
|
||
|
best = new(oa_model.TimeOptionBest)
|
||
|
for i := 0; i < len(times); i++ {
|
||
|
best.Times = append(best.Times, &oa_model.TimeOption{
|
||
|
OnWorkTime: times[i].OnWorkTime,
|
||
|
OffWorkTime: times[i].OffWorkTime,
|
||
|
})
|
||
|
}
|
||
|
|
||
|
startDay, endDay, err := WorkingTimeWeekBest(in)
|
||
|
if err != nil {
|
||
|
return best, err
|
||
|
}
|
||
|
|
||
|
if startDay == 7 {
|
||
|
startDay = 0
|
||
|
}
|
||
|
if endDay == 7 {
|
||
|
endDay = 0
|
||
|
}
|
||
|
|
||
|
best.Week = strings.Join([]string{strconv.Itoa(startDay), strconv.Itoa(endDay)}, ",")
|
||
|
|
||
|
return
|
||
|
}
|
||
|
|
||
|
// 婚假
|
||
|
func MaritalLeave(req *oa_model.CheckLeave, setting *oa.OaSettingRes) (res *oa_model.CheckLeaveRes, err error) {
|
||
|
|
||
|
res = new(oa_model.CheckLeaveRes)
|
||
|
res.OtherLeave.StartTime = req.StartTime
|
||
|
|
||
|
// 判断 是否存在国假
|
||
|
startTime, _ := time.Parse("2006-01-02", req.StartTime)
|
||
|
|
||
|
var i int32 = 1
|
||
|
next:
|
||
|
respData, _ := holiday.GetSingleData(holiday.ConvertTime(startTime.Format("2006-01-02")), true)
|
||
|
if respData.Type == 1 && respData.TypeDes != "休息日" && i <= 3 { // 节假日
|
||
|
i++
|
||
|
} else if respData.Type == 0 || (respData.Type == 1 && respData.TypeDes == "休息日") { // 工作日 || 休息日
|
||
|
i++
|
||
|
}
|
||
|
startTime = startTime.AddDate(0, 0, 1)
|
||
|
if i <= setting.Data[0].Value.MaritalLeaveBalance {
|
||
|
goto next
|
||
|
}
|
||
|
|
||
|
//second:
|
||
|
// endData, _ := holiday.GetSingleData(holiday.ConvertTime(startTime.Format("2006-01-02")), false)
|
||
|
// if endData.Type == 1 {
|
||
|
// startTime = startTime.AddDate(0, 0, 1)
|
||
|
// goto second
|
||
|
// }
|
||
|
|
||
|
res.OtherLeave.EndTime = startTime.AddDate(0, 0, -1).Format("2006-01-02")
|
||
|
res.CommonLeave.Total = float32(setting.Data[0].Value.MaritalLeaveBalance)
|
||
|
return
|
||
|
}
|
||
|
|
||
|
func OtherLeave(startDate string, Days int, startM string) (endDate, endM string) {
|
||
|
if startDate == "" || startM == "" {
|
||
|
return "", ""
|
||
|
}
|
||
|
start, _ := time.Parse("2006-01-02", startDate)
|
||
|
if startM == "上午" {
|
||
|
endDate = start.AddDate(0, 0, Days-1).Format("2006-01-02")
|
||
|
endM = "下午"
|
||
|
} else if startM == "下午" {
|
||
|
endDate = start.AddDate(0, 0, Days).Format("2006-01-02")
|
||
|
endM = "上午"
|
||
|
}
|
||
|
return
|
||
|
}
|
||
|
|
||
|
// 余额
|
||
|
func BalanceLeave(workYear float32, enterDate string, nowTime time.Time, req *oa_model.CheckLeave, setting *oa.OaSettingRes, apply *oa.ApplyRecordRes, overTimeApply *oa.ApplyRecordRes, leaveApply *oa.LeaveApplyInfoRes) (res *oa_model.CheckLeaveRes, err error) {
|
||
|
res = new(oa_model.CheckLeaveRes)
|
||
|
|
||
|
switch req.ApplyType {
|
||
|
case oa_model.TypeAnnualLeave: // 年假
|
||
|
/* 年假不在计算 */
|
||
|
/*for i := 0; i < len(setting.Data[0].Value.AnnualLeaveBalance); i++ {
|
||
|
if workYear >= float32(setting.Data[0].Value.AnnualLeaveBalance[i].Start) && (setting.Data[0].Value.AnnualLeaveBalance[i].Start != 0 || setting.Data[0].Value.AnnualLeaveBalance[i].End == 0) {
|
||
|
if workYear >= 2 {
|
||
|
enterTime, _ := time.Parse("2006-01-02", enterDate)
|
||
|
enterTime.AddDate(int(setting.Data[0].Value.AnnualLeaveBalance[i].Start), 0, 0)
|
||
|
if !time.Date(nowTime.Year(), 1, 1, 0, 0, 0, 0, time.Local).Before(enterTime.AddDate(int(setting.Data[0].Value.AnnualLeaveBalance[i].Start), 0, 0)) {
|
||
|
res.CommonLeave.Total = float32(setting.Data[0].Value.AnnualLeaveBalance[i].Days)
|
||
|
} else {
|
||
|
if i > 1 {
|
||
|
res.CommonLeave.Total = float32(setting.Data[0].Value.AnnualLeaveBalance[i-1].Days)
|
||
|
}
|
||
|
}
|
||
|
} else {
|
||
|
enterDateTime, _ := time.Parse("2006-01-02", enterDate)
|
||
|
if time.Now().Year()-enterDateTime.Year() >= 1 {
|
||
|
if nowTime.Year()-enterDateTime.Year() >= 2 {
|
||
|
res.CommonLeave.Total = float32(setting.Data[0].Value.AnnualLeaveBalance[0].Days)
|
||
|
} else {
|
||
|
currentYear := time.Date(time.Now().Year(), 12, 31, 0, 0, 0, 0, time.Local)
|
||
|
res.CommonLeave.Total = float32(math.Floor(float64(currentYear.Sub(time.Date(currentYear.Year(), enterDateTime.Month(), enterDateTime.Day()-1, 0, 0, 0, 0, time.Local)).Hours()/24/365) * float64(5)))
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
for i := 0; i < len(apply.Data); i++ {
|
||
|
res.CommonLeave.Used += apply.Data[i].Days
|
||
|
}
|
||
|
res.CommonLeave.Balance = res.CommonLeave.Total - res.CommonLeave.Used
|
||
|
*/
|
||
|
|
||
|
for i := 0; i < len(apply.Data); i++ {
|
||
|
res.CommonLeave.Used += apply.Data[i].Days
|
||
|
}
|
||
|
|
||
|
res.CommonLeave.Balance = leaveApply.LeaveApply.LeaveBalance
|
||
|
|
||
|
case oa_model.TypeParentalLeave: // 育儿假
|
||
|
if leaveApply != nil {
|
||
|
//res.CommonLeave.Total = float32(leaveApply.LeaveApply.Total)
|
||
|
//res.CommonLeave.Used = float32(leaveApply.LeaveApply.Total) - leaveApply.LeaveApply.LeaveBalance
|
||
|
res.CommonLeave.Balance = leaveApply.LeaveApply.LeaveBalance
|
||
|
}
|
||
|
//for i := 0; i < len(apply.Data); i++ {
|
||
|
// res.CommonLeave.Used += apply.Data[i].Days
|
||
|
//}
|
||
|
//res.CommonLeave.Balance = res.CommonLeave.Total - res.CommonLeave.Used
|
||
|
case oa_model.TypeNursingLeave: // 独生子女护理假
|
||
|
if leaveApply != nil {
|
||
|
//res.CommonLeave.Total = float32(leaveApply.LeaveApply.Total)
|
||
|
//res.CommonLeave.Used = float32(leaveApply.LeaveApply.Total) - leaveApply.LeaveApply.LeaveBalance
|
||
|
res.CommonLeave.Balance = leaveApply.LeaveApply.LeaveBalance
|
||
|
}
|
||
|
//for i := 0; i < len(apply.Data); i++ {
|
||
|
// res.CommonLeave.Used += apply.Data[i].Days
|
||
|
//}
|
||
|
//res.CommonLeave.Balance = res.CommonLeave.Total - res.CommonLeave.Used
|
||
|
case oa_model.TypeSick: // 病假
|
||
|
for i := 0; i < len(setting.Data[0].Value.SickBalance); i++ {
|
||
|
if workYear >= float32(setting.Data[0].Value.SickBalance[i].Start) && workYear < float32(setting.Data[0].Value.SickBalance[i].End) {
|
||
|
enterTime, _ := time.Parse("2006-01-02", enterDate)
|
||
|
enterTime.AddDate(int(setting.Data[0].Value.SickBalance[i].Start), 0, 0)
|
||
|
if !time.Date(nowTime.Year(), 1, 1, 0, 0, 0, 0, time.Local).Before(enterTime.AddDate(int(setting.Data[0].Value.SickBalance[i].Start), 0, 0)) {
|
||
|
res.CommonLeave.Total = float32(setting.Data[0].Value.SickBalance[i].Days)
|
||
|
} else {
|
||
|
if i > 1 {
|
||
|
res.CommonLeave.Total = float32(setting.Data[0].Value.SickBalance[i-1].Days)
|
||
|
}
|
||
|
}
|
||
|
} else {
|
||
|
res.CommonLeave.Total = float32(setting.Data[0].Value.SickBalance[i].Days)
|
||
|
}
|
||
|
}
|
||
|
//for i := 0; i < len(apply.Data); i++ {
|
||
|
// res.CommonLeave.Used += apply.Data[i].Days
|
||
|
//}
|
||
|
case oa_model.TypeDayOff: // 调休
|
||
|
for i := 0; i < len(overTimeApply.Data); i++ {
|
||
|
res.CommonLeave.Total += overTimeApply.Data[i].Hours
|
||
|
}
|
||
|
for i := 0; i < len(apply.Data); i++ {
|
||
|
res.CommonLeave.Used += apply.Data[i].Hours
|
||
|
}
|
||
|
res.CommonLeave.Balance = res.CommonLeave.Total - res.CommonLeave.Used
|
||
|
case oa_model.TypeMaternityLeave: // 产假
|
||
|
res.CommonLeave.Total = float32(setting.Data[0].Value.MaternityLeaveBalance.BasicDays)
|
||
|
if req.Dystocia == 1 {
|
||
|
res.CommonLeave.Total += float32(setting.Data[0].Value.MaternityLeaveBalance.Dystocia)
|
||
|
}
|
||
|
if req.Children > 1 {
|
||
|
res.CommonLeave.Total += float32(setting.Data[0].Value.MaternityLeaveBalance.OneMore * (req.Children - 1))
|
||
|
}
|
||
|
for i := 0; i < len(apply.Data); i++ {
|
||
|
res.CommonLeave.Used += apply.Data[i].Days
|
||
|
}
|
||
|
|
||
|
res.OtherLeave.StartTime = req.StartTime
|
||
|
res.OtherLeave.StartM = req.M
|
||
|
res.OtherLeave.EndTime, res.OtherLeave.EndM = OtherLeave(req.StartTime, int(res.CommonLeave.Total), req.M)
|
||
|
case oa_model.TypeAbortLeave: // 流产假
|
||
|
for i := 0; i < len(setting.Data[0].Value.AbortLeaveBalance); i++ {
|
||
|
if req.Month >= setting.Data[0].Value.AbortLeaveBalance[i].Start && req.Month <= setting.Data[0].Value.AbortLeaveBalance[i].End {
|
||
|
res.CommonLeave.Total = float32(setting.Data[0].Value.AbortLeaveBalance[i].Days)
|
||
|
} else if req.Month >= setting.Data[0].Value.AbortLeaveBalance[i].Start && setting.Data[0].Value.AbortLeaveBalance[i].End == 0 {
|
||
|
res.CommonLeave.Total = float32(setting.Data[0].Value.AbortLeaveBalance[i].Days)
|
||
|
}
|
||
|
}
|
||
|
for i := 0; i < len(apply.Data); i++ {
|
||
|
res.CommonLeave.Used += apply.Data[i].Days
|
||
|
}
|
||
|
|
||
|
res.OtherLeave.StartTime = req.StartTime
|
||
|
res.OtherLeave.StartM = req.M
|
||
|
res.OtherLeave.EndTime, res.OtherLeave.EndM = OtherLeave(req.StartTime, int(res.CommonLeave.Total), req.M)
|
||
|
case oa_model.TypePaternityLeave: // 陪产假
|
||
|
res.CommonLeave.Total = float32(setting.Data[0].Value.PaternityLeaveBalance)
|
||
|
for i := 0; i < len(apply.Data); i++ {
|
||
|
res.CommonLeave.Used += apply.Data[i].Days
|
||
|
}
|
||
|
res.OtherLeave.StartTime = req.StartTime
|
||
|
res.OtherLeave.StartM = req.M
|
||
|
res.OtherLeave.EndTime, res.OtherLeave.EndM = OtherLeave(req.StartTime, int(res.CommonLeave.Total), req.M)
|
||
|
case oa_model.TypeMatingCheckLeave: // 孕检假
|
||
|
for i := 0; i < len(setting.Data[0].Value.MatingCheckLeaveBalance); i++ {
|
||
|
if req.Month >= setting.Data[0].Value.MatingCheckLeaveBalance[i].Start && req.Month <= setting.Data[0].Value.MatingCheckLeaveBalance[i].End {
|
||
|
res.CommonLeave.Total = float32(setting.Data[0].Value.MatingCheckLeaveBalance[i].Months)
|
||
|
} else if req.Month >= setting.Data[0].Value.MatingCheckLeaveBalance[i].Start && setting.Data[0].Value.MatingCheckLeaveBalance[i].End == 0 {
|
||
|
res.CommonLeave.Total = float32(setting.Data[0].Value.MatingCheckLeaveBalance[i].Weeks)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
for i := 0; i < len(apply.Data); i++ {
|
||
|
res.CommonLeave.Used++
|
||
|
}
|
||
|
res.CommonLeave.Balance = res.CommonLeave.Total - res.CommonLeave.Used
|
||
|
// 暂时默认为 1
|
||
|
res.CommonLeave.Total = 1
|
||
|
res.OtherLeave.StartTime = req.StartTime
|
||
|
res.OtherLeave.StartM = req.M
|
||
|
res.OtherLeave.EndTime, res.OtherLeave.EndM = OtherLeave(req.StartTime, 1, req.M)
|
||
|
//case oa_model.TypeFuneralLeave: // 丧假
|
||
|
// res.CommonLeave.Total = float32(setting.Data[0].Value.FuneralLeaveBalance)
|
||
|
// res.OtherLeave.StartTime = req.StartTime
|
||
|
// res.OtherLeave.StartM = req.M
|
||
|
// res.OtherLeave.EndTime, res.OtherLeave.EndM = OtherLeave(req.StartTime, int(res.CommonLeave.Total), req.M)
|
||
|
case oa_model.TypeMaritalLeave: // 婚假
|
||
|
res.CommonLeave.Total = float32(setting.Data[0].Value.MaritalLeaveBalance)
|
||
|
for i := 0; i < len(apply.Data); i++ {
|
||
|
res.CommonLeave.Used += apply.Data[i].Days
|
||
|
}
|
||
|
res.OtherLeave.StartTime = req.StartTime
|
||
|
res.OtherLeave.StartM = req.M
|
||
|
res.OtherLeave.EndTime, res.OtherLeave.EndM = OtherLeave(req.StartTime, int(res.CommonLeave.Total), req.M)
|
||
|
case oa_model.TypeBreastFeedingLeave: // 哺乳假
|
||
|
res.CommonLeave.Total = float32(setting.Data[0].Value.BreastFeedingLeaveBalance) * 2 * float32(req.Children)
|
||
|
for i := 0; i < len(apply.Data); i++ {
|
||
|
res.CommonLeave.Used += apply.Data[i].Hours
|
||
|
}
|
||
|
res.CommonLeave.Balance = res.CommonLeave.Total - res.CommonLeave.Used
|
||
|
}
|
||
|
|
||
|
return
|
||
|
}
|
||
|
|
||
|
func CheckLeaveHandle(checkLeaveReq *oa_model.CheckLeave, userInfo login.Info, forMoney bool) (res *oa_model.CheckLeaveRes, err error) {
|
||
|
accountInfoReq := new(account.InfoRequest)
|
||
|
accountInfoReq.ID = userInfo.ID
|
||
|
// 工作年限
|
||
|
accountInfoRes, err := AccountProvider.Info(context.Background(), accountInfoReq)
|
||
|
if err != nil {
|
||
|
return
|
||
|
}
|
||
|
|
||
|
// 设置查询
|
||
|
oaSettingReq := new(oa.OaSettingReq)
|
||
|
oaSettingRes := new(oa.OaSettingRes)
|
||
|
keyword := oa_model.SettingKeyWordMap[checkLeaveReq.ApplyType]
|
||
|
if keyword != "" {
|
||
|
oaSettingReq.Keyword = keyword
|
||
|
oaSettingRes, err = GrpcOAImpl.QueryOaSetting(context.Background(), oaSettingReq)
|
||
|
if err != nil || len(oaSettingRes.Data) != 1 {
|
||
|
//service.ResponseMsg(c, e.SUCCESS, serializer.Response{
|
||
|
// Msg: e.ERR_QUERY_OA_SETTING,
|
||
|
// Status: e.Failed,
|
||
|
//})
|
||
|
return res, errors.New(e.ErrQueryOaSetting)
|
||
|
}
|
||
|
} else if checkLeaveReq.ApplyType != oa_model.TypeDayOff {
|
||
|
//service.ResponseMsg(c, e.SUCCESS, serializer.Response{
|
||
|
// Msg: e.ERR_NOT_NEED_BALANCE,
|
||
|
// Status: e.Ok,
|
||
|
//})
|
||
|
//return res, errors.New(e.ERR_NOT_NEED_BALANCE)
|
||
|
return res, nil
|
||
|
}
|
||
|
|
||
|
// 申请请假查询
|
||
|
nowTime := time.Now()
|
||
|
var StartTime time.Time
|
||
|
var year string
|
||
|
var month string
|
||
|
if checkLeaveReq.StartTime != "" {
|
||
|
StartTime, _ = time.Parse("2006-01-02", checkLeaveReq.StartTime)
|
||
|
year = StartTime.Format("2006")
|
||
|
month = common.CurrentMonth() + "-25"
|
||
|
} else {
|
||
|
year = nowTime.Format("2006")
|
||
|
month = common.CurrentMonth() + "-25"
|
||
|
}
|
||
|
|
||
|
// 特殊处理 调休
|
||
|
if checkLeaveReq.ApplyType == oa_model.TypeDayOff && !forMoney {
|
||
|
res = new(oa_model.CheckLeaveRes)
|
||
|
var checkDayOffBalanceErr error
|
||
|
res.CommonLeave.Balance, checkDayOffBalanceErr = CheckDayOffBalance(userInfo.ID)
|
||
|
if checkDayOffBalanceErr != nil {
|
||
|
return nil, checkDayOffBalanceErr
|
||
|
}
|
||
|
return res, nil
|
||
|
}
|
||
|
|
||
|
applyReq := new(oa.ApplyRecordReq)
|
||
|
applyReq.StaffUID = userInfo.ID
|
||
|
applyReq.ApplyType = []string{checkLeaveReq.ApplyType}
|
||
|
applyReq.ApplyStatus = []int32{e.ApprovalWorkStatusDoing, e.ApprovalWorkStatusOk, e.ApprovalWorkStatusRevoking}
|
||
|
applyReq.Page = 1
|
||
|
applyReq.PageSize = 9999
|
||
|
applyRes := new(oa.ApplyRecordRes)
|
||
|
overTimeApply := new(oa.ApplyRecordRes)
|
||
|
if checkLeaveReq.ApplyType == oa_model.TypeParentalLeave || checkLeaveReq.ApplyType == oa_model.TypeAnnualLeave || checkLeaveReq.ApplyType == oa_model.TypeNursingLeave || checkLeaveReq.ApplyType == oa_model.TypeSick {
|
||
|
applyReq.BeginTime = year + "-01-01"
|
||
|
applyReq.EndTime = year + "-12-31"
|
||
|
} else if checkLeaveReq.ApplyType == oa_model.TypeDayOff {
|
||
|
dates := holiday.SplitMonthV1(month, "2006-01-02")
|
||
|
applyReq.BeginTime = dates[0]
|
||
|
applyReq.EndTime = dates[len(dates)-1]
|
||
|
|
||
|
overTimeApplyReq := new(oa.ApplyRecordReq)
|
||
|
_ = copier.CopyWithOption(&overTimeApplyReq, applyReq, copier.Option{DeepCopy: true})
|
||
|
overTimeApplyReq.ApplyStatus = []int32{e.ApprovalWorkStatusOk}
|
||
|
overTimeApplyReq.ApplyType = []string{oa_model.TypeOverTime}
|
||
|
overTimeApplyReq.BeginTime = dates[0]
|
||
|
overTimeApplyReq.EndTime = dates[len(dates)-1]
|
||
|
overTimeApply, err = GrpcOAImpl.QueryOaApply(context.Background(), overTimeApplyReq)
|
||
|
if err != nil {
|
||
|
return nil, errors.New(e.ErrQueryOaApply)
|
||
|
}
|
||
|
for i := 0; i < len(overTimeApply.Data); i++ {
|
||
|
if !CheckDateInMonth(overTimeApply.Data[i].ApplyTimes[0].Date, dates) {
|
||
|
overTimeApply.Data = append(overTimeApply.Data[:i], overTimeApply.Data[i+1:]...)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
} else if checkLeaveReq.ApplyType == oa_model.TypeMatingCheckLeave {
|
||
|
for i := 0; i < len(oaSettingRes.Data[0].Value.MatingCheckLeaveBalance); i++ {
|
||
|
if checkLeaveReq.Month >= oaSettingRes.Data[0].Value.MatingCheckLeaveBalance[i].Start && checkLeaveReq.Month <= oaSettingRes.Data[0].Value.MatingCheckLeaveBalance[i].End {
|
||
|
dates := holiday.SplitMonthV1(month, "2006-01-02")
|
||
|
applyReq.BeginTime = dates[0]
|
||
|
applyReq.EndTime = dates[len(dates)-1]
|
||
|
} else if checkLeaveReq.Month >= oaSettingRes.Data[0].Value.MatingCheckLeaveBalance[i].Start && oaSettingRes.Data[0].Value.MatingCheckLeaveBalance[i].End == 0 {
|
||
|
applyReq.BeginTime, applyReq.EndTime = holiday.CurrentWeek(StartTime)
|
||
|
}
|
||
|
}
|
||
|
} else if checkLeaveReq.ApplyType == oa_model.TypeBreastFeedingLeave {
|
||
|
currentDate := nowTime.Format("2006-01-02")
|
||
|
if checkLeaveReq.StartTime != "" {
|
||
|
currentDate = checkLeaveReq.StartTime
|
||
|
}
|
||
|
applyReq.BeginTime = currentDate
|
||
|
applyReq.EndTime = currentDate
|
||
|
}
|
||
|
|
||
|
fmt.Println("========= applyReq 1 ========================= ")
|
||
|
fmt.Printf("=== %+v\n", applyReq)
|
||
|
fmt.Println("========= applyReq 2 ========================= ")
|
||
|
|
||
|
applyRes, err = GrpcOAImpl.QueryOaApply(context.Background(), applyReq)
|
||
|
if err != nil {
|
||
|
return nil, errors.New(e.ErrQueryOaApply)
|
||
|
}
|
||
|
fmt.Println("========= QueryOaApply 1 ========================= ")
|
||
|
fmt.Printf("=== %+v\n", applyRes.Data)
|
||
|
fmt.Println("========= QueryOaApply 2 ========================= ")
|
||
|
|
||
|
// 查询余额申请 育儿假 独生子女护理假
|
||
|
/* 丢弃 2025-01-06 */
|
||
|
/*
|
||
|
leaveApplyRes := new(oa.LeaveApplyInfoRes)
|
||
|
if checkLeaveReq.ApplyType == oa_model.TypeParentalLeave || checkLeaveReq.ApplyType == oa_model.TypeNursingLeave {
|
||
|
leaveApplyReq := new(oa.LeaveApplyInfoReq)
|
||
|
leaveApplyReq.StaffUID = userInfo.ID
|
||
|
leaveApplyReq.LeaveApplyType = e.CheckLeaveApplyMap[checkLeaveReq.ApplyType]
|
||
|
leaveApplyReq.IsOver = e.IsNotOver
|
||
|
leaveApplyReq.UsefulTime = year
|
||
|
leaveApplyRes, err = GrpcOAImpl.QueryLeaveApplyInfo(context.Background(), leaveApplyReq)
|
||
|
if err != nil {
|
||
|
if err.Error() == e.ErrNotHaveBalance {
|
||
|
return nil, err
|
||
|
} else {
|
||
|
return nil, errors.New(e.ErrQueryOaLeaveApply)
|
||
|
}
|
||
|
}
|
||
|
}*/
|
||
|
|
||
|
leaveApplyRes := new(oa.LeaveApplyInfoRes)
|
||
|
leaveApplyRes.LeaveApply = new(oa.LeaveApply)
|
||
|
if checkLeaveReq.ApplyType == oa_model.TypeParentalLeave || checkLeaveReq.ApplyType == oa_model.TypeNursingLeave || checkLeaveReq.ApplyType == oa_model.TypeAnnualLeave {
|
||
|
var leaveBalanceInfoReq *oa.LeaveBalanceInfoReq
|
||
|
var leaveBalanceInfoRes *oa.LeaveBalance
|
||
|
leaveBalanceInfoReq = new(oa.LeaveBalanceInfoReq)
|
||
|
leaveBalanceInfoReq.StaffUID = userInfo.ID
|
||
|
yearInt, _ := strconv.Atoi(year)
|
||
|
leaveBalanceInfoReq.Year = int32(yearInt)
|
||
|
leaveBalanceInfoRes, err = GrpcOAImpl.GetLeaveBalanceInfo(context.Background(), leaveBalanceInfoReq)
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
|
||
|
if leaveBalanceInfoRes != nil {
|
||
|
if checkLeaveReq.ApplyType == oa_model.TypeParentalLeave {
|
||
|
if leaveBalanceInfoRes.ParentalLeave > 0 {
|
||
|
leaveApplyRes.LeaveApply.LeaveBalance = leaveBalanceInfoRes.ParentalLeave
|
||
|
} else {
|
||
|
return nil, errors.New(e.ErrNoBalance)
|
||
|
}
|
||
|
}
|
||
|
if checkLeaveReq.ApplyType == oa_model.TypeNursingLeave {
|
||
|
if leaveBalanceInfoRes.NursingLeave > 0 {
|
||
|
leaveApplyRes.LeaveApply.LeaveBalance = leaveBalanceInfoRes.NursingLeave
|
||
|
} else {
|
||
|
return nil, errors.New(e.ErrNoBalance)
|
||
|
}
|
||
|
}
|
||
|
if checkLeaveReq.ApplyType == oa_model.TypeAnnualLeave {
|
||
|
if leaveBalanceInfoRes.AnnualLeave > 0 {
|
||
|
leaveApplyRes.LeaveApply.LeaveBalance = leaveBalanceInfoRes.AnnualLeave
|
||
|
} else {
|
||
|
return nil, errors.New(e.ErrNoBalance)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
// 婚假 暂时先不单独处理
|
||
|
//if req.ApplyType == oa_model.TypeMaritalLeave {
|
||
|
// res, err = MaritalLeave(req, oaSettingRes)
|
||
|
//}
|
||
|
res, err = BalanceLeave(accountInfoRes.Info.WorkYear, accountInfoRes.Info.EnterDate, nowTime, checkLeaveReq, oaSettingRes, applyRes, overTimeApply, leaveApplyRes) // 育儿假
|
||
|
|
||
|
return
|
||
|
}
|
||
|
|
||
|
func VerifyTimeOrder(applyTimes []oa_model.ApplyTime) error {
|
||
|
if len(applyTimes) != 2 {
|
||
|
return errors.New(e.ErrApplyTime)
|
||
|
}
|
||
|
|
||
|
start, _ := time.ParseInLocation("2006-01-02", applyTimes[0].Date, time.Local)
|
||
|
end, _ := time.ParseInLocation("2006-01-02", applyTimes[1].Date, time.Local)
|
||
|
|
||
|
if !start.After(end) {
|
||
|
if applyTimes[0].M != "" || applyTimes[1].M != "" {
|
||
|
if start.Equal(end) {
|
||
|
if applyTimes[0].M == "下午" && applyTimes[1].M == "上午" {
|
||
|
return errors.New(e.ErrTimeOrder)
|
||
|
}
|
||
|
}
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
if applyTimes[0].Hour != "" && applyTimes[1].Hour != "" {
|
||
|
if start.Equal(end) {
|
||
|
startTime, _ := time.ParseInLocation("2006-01-02 15:04:05", applyTimes[0].Date+" "+applyTimes[0].Hour+":00", time.Local)
|
||
|
endTime, _ := time.ParseInLocation("2006-01-02 15:04:05", applyTimes[1].Date+" "+applyTimes[1].Hour+":00", time.Local)
|
||
|
if startTime.After(endTime) {
|
||
|
return errors.New(e.ErrTimeOrder)
|
||
|
}
|
||
|
}
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
}
|
||
|
return errors.New(e.ErrTimeOrder)
|
||
|
}
|
||
|
|
||
|
func CheckWifi(ip string) (isInWifi bool, err error) {
|
||
|
req := new(oa.OaSettingReq)
|
||
|
|
||
|
req.Keyword = e.ChickInWifi
|
||
|
|
||
|
isInWifi = false
|
||
|
|
||
|
res, err := GrpcOAImpl.QueryOaSetting(context.Background(), req)
|
||
|
if err != nil {
|
||
|
return isInWifi, err
|
||
|
}
|
||
|
|
||
|
if res.Data != nil {
|
||
|
for i := 0; i < len(res.Data); i++ {
|
||
|
for _, ipOpt := range res.Data[i].Value.ChickInWifiOptions.IP {
|
||
|
if ip == ipOpt {
|
||
|
isInWifi = true
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return isInWifi, err
|
||
|
}
|
||
|
|
||
|
// CheckDayOffBalance 统计 前两个月的 加班时间 和 调休时间
|
||
|
func CheckDayOffBalance(staffUID uint64) (balance float32, err error) {
|
||
|
_, _, balance, err = checkSingleDayOffBalance(staffUID, common.CurrentMonth())
|
||
|
return balance, err
|
||
|
}
|
||
|
|
||
|
// checkSingleDayOffBalance 统计单个月的加班时间和调休时间
|
||
|
// 截止至 2024-12
|
||
|
func checkSingleDayOffBalance(staffUID uint64, inMonth string) (overTime float32, dayOff float32, balance float32, err error) {
|
||
|
dates := make([]string, 0)
|
||
|
var month string
|
||
|
|
||
|
if len(strings.Split(inMonth, "-")) == 2 {
|
||
|
month = common.Add25ForMonth(inMonth)
|
||
|
} else if len(strings.Split(inMonth, "-")) == 3 {
|
||
|
month = inMonth
|
||
|
}
|
||
|
dates = holiday.SplitMonthV1(month, "2006-01-02")
|
||
|
|
||
|
// 上个月 根据 传入的月份 获取上个月的月份
|
||
|
preMonth := common.PreMonth(inMonth)
|
||
|
preMonth = common.Add25ForMonth(preMonth)
|
||
|
preDates := holiday.SplitMonthV1(preMonth, "2006-01-02")
|
||
|
|
||
|
// 加班时间
|
||
|
overTimeApplyReq := new(oa.ApplyRecordReq)
|
||
|
overTimeApplyReq.StaffUID = staffUID
|
||
|
overTimeApplyReq.ApplyType = []string{oa_model.TypeOverTime}
|
||
|
overTimeApplyReq.ApplyStatus = []int32{e.ApprovalWorkStatusOk}
|
||
|
overTimeApplyReq.Page = 1
|
||
|
overTimeApplyReq.PageSize = 9999
|
||
|
overTimeApplyReq.BeginTime = dates[0]
|
||
|
overTimeApplyReq.EndTime = dates[len(dates)-1]
|
||
|
|
||
|
overTimeApplyRes, overTimeApplyResErr := GrpcOAImpl.QueryOaApply(context.Background(), overTimeApplyReq)
|
||
|
if overTimeApplyResErr != nil {
|
||
|
return 0, 0, 0, overTimeApplyResErr
|
||
|
}
|
||
|
|
||
|
fmt.Println("========= overTimeApplyRes 1 ========================= ")
|
||
|
|
||
|
fmt.Printf("month := %+v\n", month)
|
||
|
|
||
|
fmt.Printf("=== %+v\n", overTimeApplyRes.Data)
|
||
|
|
||
|
overTime = 0
|
||
|
for i := 0; i < len(overTimeApplyRes.Data); i++ {
|
||
|
overTime += overTimeApplyRes.Data[i].Hours
|
||
|
}
|
||
|
|
||
|
fmt.Printf("=== overTime is :%+v\n", overTime)
|
||
|
|
||
|
fmt.Println("========= overTimeApplyRes 2 ========================= ")
|
||
|
|
||
|
// 调休时间
|
||
|
dayOffApplyReq := new(oa.ApplyRecordReq)
|
||
|
dayOffApplyReq.StaffUID = staffUID
|
||
|
dayOffApplyReq.ApplyType = []string{oa_model.TypeDayOff}
|
||
|
dayOffApplyReq.ApplyStatus = []int32{e.ApprovalWorkStatusDoing, e.ApprovalWorkStatusOk, e.ApprovalWorkStatusRevoking}
|
||
|
dayOffApplyReq.Page = 1
|
||
|
dayOffApplyReq.PageSize = 9999
|
||
|
dayOffApplyReq.BeginTime = dates[0]
|
||
|
dayOffApplyReq.EndTime = dates[len(dates)-1]
|
||
|
dayOffApplyRes, dayOffApplyResErr := GrpcOAImpl.QueryOaApply(context.Background(), dayOffApplyReq)
|
||
|
if dayOffApplyResErr != nil {
|
||
|
return 0, 0, 0, dayOffApplyResErr
|
||
|
}
|
||
|
|
||
|
fmt.Println("========= dayOffApplyRes 1 ========================= ")
|
||
|
|
||
|
for i := 0; i < len(dayOffApplyRes.Data); i++ {
|
||
|
dayOff += dayOffApplyRes.Data[i].Hours
|
||
|
}
|
||
|
fmt.Printf("=== dayOff is :%+v\n", dayOff)
|
||
|
fmt.Println("========= dayOffApplyRes 2 ========================= ")
|
||
|
|
||
|
retTime, _ := time.Parse("2006-01-02", dates[0])
|
||
|
pointTime, _ := time.Parse("2006-01-02", "2024-11-25")
|
||
|
|
||
|
if retTime.Before(pointTime) {
|
||
|
balance = float32(math.Floor(float64(overTime-dayOff)*10) / 10)
|
||
|
fmt.Printf("retTime.Before(pointTime) \n === balance is :%+v\n", balance)
|
||
|
return overTime, dayOff, balance, nil
|
||
|
}
|
||
|
|
||
|
var preBalance float32
|
||
|
|
||
|
// 上个月的 加班时间
|
||
|
preOverTimeApplyReq := new(oa.ApplyRecordReq)
|
||
|
preOverTimeApplyReq.StaffUID = staffUID
|
||
|
preOverTimeApplyReq.ApplyType = []string{oa_model.TypeOverTime}
|
||
|
preOverTimeApplyReq.ApplyStatus = []int32{e.ApprovalWorkStatusOk}
|
||
|
preOverTimeApplyReq.Page = 1
|
||
|
preOverTimeApplyReq.PageSize = 9999
|
||
|
preOverTimeApplyReq.BeginTime = preDates[0]
|
||
|
preOverTimeApplyReq.EndTime = preDates[len(preDates)-1]
|
||
|
|
||
|
preOverTimeApplyRes, preOverTimeApplyResErr := GrpcOAImpl.QueryOaApply(context.Background(), preOverTimeApplyReq)
|
||
|
if preOverTimeApplyResErr != nil {
|
||
|
return 0, 0, 0, preOverTimeApplyResErr
|
||
|
}
|
||
|
|
||
|
fmt.Println("========= pre overTimeApplyRes 1 ========================= ")
|
||
|
|
||
|
fmt.Printf("preMonth := %+v\n", preMonth)
|
||
|
|
||
|
fmt.Printf("=== %+v\n", overTimeApplyRes.Data)
|
||
|
|
||
|
var preOverTime float32 = 0
|
||
|
for i := 0; i < len(preOverTimeApplyRes.Data); i++ {
|
||
|
preOverTime += preOverTimeApplyRes.Data[i].Hours
|
||
|
}
|
||
|
|
||
|
fmt.Printf("=== preOverTime is :%+v\n", preOverTime)
|
||
|
fmt.Println("========= pre overTimeApplyRes 2 ========================= ")
|
||
|
|
||
|
// 上个月的 调休时间
|
||
|
preDayOffApplyReq := new(oa.ApplyRecordReq)
|
||
|
preDayOffApplyReq.StaffUID = staffUID
|
||
|
preDayOffApplyReq.ApplyType = []string{oa_model.TypeDayOff}
|
||
|
preDayOffApplyReq.ApplyStatus = []int32{e.ApprovalWorkStatusDoing, e.ApprovalWorkStatusOk, e.ApprovalWorkStatusRevoking}
|
||
|
preDayOffApplyReq.Page = 1
|
||
|
preDayOffApplyReq.PageSize = 9999
|
||
|
preDayOffApplyReq.BeginTime = preDates[0]
|
||
|
preDayOffApplyReq.EndTime = preDates[len(preDates)-1]
|
||
|
preDayOffApplyRes, preDayOffApplyResErr := GrpcOAImpl.QueryOaApply(context.Background(), preDayOffApplyReq)
|
||
|
if preDayOffApplyResErr != nil {
|
||
|
return 0, 0, 0, preDayOffApplyResErr
|
||
|
}
|
||
|
|
||
|
fmt.Println("========= pre dayOffApplyRes 1 ========================= ")
|
||
|
|
||
|
var preDayOff float32 = 0
|
||
|
for i := 0; i < len(preDayOffApplyRes.Data); i++ {
|
||
|
preDayOff += preDayOffApplyRes.Data[i].Hours
|
||
|
}
|
||
|
|
||
|
fmt.Printf("=== preDayOff is :%+v\n", preDayOff)
|
||
|
fmt.Println("========= pre dayOffApplyRes 2 ========================= ")
|
||
|
|
||
|
prePreMonth := common.PreMonth(preMonth)
|
||
|
|
||
|
// 上上个月的 可用
|
||
|
_, _, prePreBalance, prePreBalanceErr := checkSingleDayOffBalance(staffUID, prePreMonth)
|
||
|
if prePreBalanceErr != nil {
|
||
|
return 0, 0, 0, prePreBalanceErr
|
||
|
}
|
||
|
|
||
|
fmt.Println("========= prePreBalance 1 ========================= ")
|
||
|
fmt.Printf("=== prePreBalance is :%+v\n", prePreBalance)
|
||
|
fmt.Println("========= prePreBalance 2 ========================= ")
|
||
|
|
||
|
if prePreBalance-preDayOff > 0 {
|
||
|
preBalance = preOverTime
|
||
|
} else {
|
||
|
preBalance = preOverTime + prePreBalance - preDayOff
|
||
|
}
|
||
|
|
||
|
fmt.Println("========= preBalance 1 ========================= ")
|
||
|
fmt.Printf("=== preBalance is :%+v\n", preBalance)
|
||
|
fmt.Println("========= preBalance 2 ========================= ")
|
||
|
|
||
|
balance = overTime + preBalance - dayOff
|
||
|
|
||
|
fmt.Println("========= balance 1 ========================= ")
|
||
|
fmt.Printf("=== balance is :%+v\n", balance)
|
||
|
fmt.Println("========= balance 2 ========================= ")
|
||
|
|
||
|
return overTime, dayOff, balance, nil
|
||
|
}
|