作者 yangfu

chore: 工时统计算法更新、代码优化

... ... @@ -59,23 +59,14 @@ func (d *AttendanceRecordDto) LoadDto(m *domain.ProductAttendanceRecord, orgId i
d.WorkTimeAfter = m.WorkTimeAfter
d.AttendanceStatus = m.AttendanceStatus
d.AuthFlag = domain.CheckOrgAuth(orgId, m.OrgId)
if m.Ext != nil {
d.OrgName = m.Ext.OrgName
//d.ProductAttendanceRecordExt = m.Ext.AttendanceExt
//if
if m.Ext.AttendanceExt != nil {
if m.Ext.AttendanceExt.ApproveUserId > 0 {
d.ApproveUser = &domain.User{
UserId: m.Ext.AttendanceExt.ApproveUserId,
UserName: m.Ext.AttendanceExt.ApproveUserName,
}
}
d.ApproveUser = m.ApproveUser()
d.GroupName = m.GroupName()
if m.Ext != nil && m.Ext.AttendanceExt != nil {
if m.Ext.AttendanceExt.ApproveAt > 0 {
t := time.Unix(m.Ext.AttendanceExt.ApproveAt, 0)
d.ApproveAt = t.Local().Format("2006-01-02 15:04:05")
}
d.GroupName = m.Ext.AttendanceExt.GroupName
}
}
return d
}
... ...
... ... @@ -51,12 +51,7 @@ func (d *EmployeeAttendanceRecordDto) LoadDto(m *domain.ProductAttendanceRecord,
d.EmployeeTypeDescription = domain.EmployeeTypeDescription(m.ProductWorker.EmployeeType)
d.AttendanceStatusDescription = domain.AttendanceStatusDescription(m.AttendanceStatus)
d.AuthFlag = domain.CheckOrgAuth(orgId, m.OrgId)
if m.Ext != nil {
d.OrgName = m.Ext.OrgName
//d.ProductAttendanceRecordExt = m.Ext.AttendanceExt
if m.Ext.AttendanceExt != nil {
d.GroupName = m.Ext.AttendanceExt.GroupName
}
}
d.GroupName = m.GroupName()
return d
}
... ...
... ... @@ -34,9 +34,6 @@ func (d *WorkshopWorkTimeRecordDto) LoadDto(m *domain.WorkshopWorkTimeRecord, or
d.WorkStation = m.WorkStation
d.RecordDate = m.RecordDate.Local().Format("2006-01-02")
d.AuthFlag = domain.CheckOrgAuth(orgId, m.OrgId)
if m.Ext != nil {
d.OrgName = m.Ext.OrgName
//d.ProductAttendanceRecordExt = m.Ext.AttendanceExt
}
return d
}
... ...
... ... @@ -119,7 +119,7 @@ func (attendanceService *AttendanceService) CreateAttendance(operateInfo *domain
ProductGroupId: productGroup.ProductGroupId,
}),
}
newAttendance.WorkTimeBefore = newAttendance.ComputeWorkTimeBefore()
newAttendance.WorkTimeBefore = newAttendance.ComputeWorkTimeBefore(nil)
var attendanceRepository domain.ProductAttendanceRecordRepository
attendanceRepository, _, _ = factory.FastPgAttendance(transactionContext, 0)
... ...
... ... @@ -2,6 +2,7 @@ package domain
import (
"errors"
"github.com/linmadan/egglib-go/utils/xtime"
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/infrastructure/utils"
"time"
)
... ... @@ -65,7 +66,7 @@ func (productAttendanceRecord *ProductAttendanceRecord) Update(data map[string]i
}
// 计算审核前工时
func (productAttendanceRecord *ProductAttendanceRecord) ComputeWorkTimeBefore() float64 {
func (productAttendanceRecord *ProductAttendanceRecord) ComputeWorkTimeBefore(productCalendar *ProductCalendar) float64 {
if productAttendanceRecord.SignIn.IsZero() {
return 0
}
... ... @@ -75,7 +76,32 @@ func (productAttendanceRecord *ProductAttendanceRecord) ComputeWorkTimeBefore()
if !productAttendanceRecord.SignOut.After(productAttendanceRecord.SignIn) {
return 0
}
return utils.Round(productAttendanceRecord.SignOut.Sub(productAttendanceRecord.SignIn).Hours(), 1)
wt := utils.Round(productAttendanceRecord.SignOut.Sub(productAttendanceRecord.SignIn).Hours(), 1)
if productCalendar == nil {
return wt
}
wt = wt - productCalendar.BreakTime
if wt < 0 {
return 0
}
return wt
}
func (productAttendanceRecord *ProductAttendanceRecord) SetProductTimeByProductCalendar(productCalendar *ProductCalendar) error {
now := xtime.New(productAttendanceRecord.SignIn)
productAttendanceRecord.Ext.AttendanceExt.ProductTime = now.BeginningOfDay().Unix()
if productCalendar == nil {
return nil
}
overDay, err := productCalendar.CheckOverDay(productAttendanceRecord.SignIn)
if err != nil {
return nil
}
newNow := now.BeginningOfDay().Add(-time.Hour * 24)
if overDay && productCalendar.MatchCalendarSelected(newNow) {
productAttendanceRecord.Ext.AttendanceExt.ProductTime = newNow.Unix()
}
return nil
}
func (productAttendanceRecord *ProductAttendanceRecord) Approve(approveUser *User, workTimeAfter float64, status int) error {
... ... @@ -94,3 +120,40 @@ func (productAttendanceRecord *ProductAttendanceRecord) Approve(approveUser *Use
}
return nil
}
func (productAttendanceRecord *ProductAttendanceRecord) ProductTime() time.Time {
attendanceExt := productAttendanceRecord.Ext.AttendanceExt
if attendanceExt != nil && attendanceExt.ProductTime > 0 {
t := time.Unix(attendanceExt.ProductTime, 0)
if !t.IsZero() {
return t
}
}
return productAttendanceRecord.SignIn
}
func (productAttendanceRecord *ProductAttendanceRecord) GroupName() string {
if productAttendanceRecord.Ext != nil {
return ""
}
if productAttendanceRecord.Ext.AttendanceExt != nil {
return ""
}
return productAttendanceRecord.Ext.AttendanceExt.GroupName
}
func (productAttendanceRecord *ProductAttendanceRecord) ApproveUser() *User {
if productAttendanceRecord.Ext != nil {
return nil
}
if productAttendanceRecord.Ext.AttendanceExt != nil {
return nil
}
if productAttendanceRecord.Ext.AttendanceExt.ApproveUserId == 0 {
return nil
}
return &User{
UserId: productAttendanceRecord.Ext.AttendanceExt.ApproveUserId,
UserName: productAttendanceRecord.Ext.AttendanceExt.ApproveUserName,
}
}
... ...
... ... @@ -6,6 +6,8 @@ type ProductAttendanceRecordExt struct {
ProductGroupId int `json:"productGroupId,omitempty"`
// 班组名称
GroupName string `json:"groupName,omitempty"`
// 生产日期
ProductTime int64 `json:"productTime,omitempty"`
// 审核人Id
ApproveUserId int `json:"approveUserId,omitempty"`
// 审核人名称
... ...
... ... @@ -2,6 +2,8 @@ package domain
import (
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/infrastructure/utils"
"strconv"
"strings"
"time"
)
... ... @@ -73,3 +75,66 @@ func (productCalendar *ProductCalendar) ResetWorkTime(v float64) error {
productCalendar.WorkTime = td.Hours() - productCalendar.BreakTime
return nil
}
func (productCalendar *ProductCalendar) MatchCalendarSelected(t time.Time) bool {
weekdays := productCalendar.CalendarSelectedToWeekDays()
for _, v := range weekdays {
if v == t.Weekday() {
return true
}
}
return false
}
func (productCalendar *ProductCalendar) CalendarSelectedToWeekDays() []time.Weekday {
weekdays := make([]time.Weekday, 0)
for _, v := range productCalendar.CalendarSelected {
switch v {
case "7": //周日
weekdays = append(weekdays, time.Sunday)
break
case "1": //"周一":
weekdays = append(weekdays, time.Monday)
break
case "2": //"周二":
weekdays = append(weekdays, time.Tuesday)
break
case "3": //"周三":
weekdays = append(weekdays, time.Wednesday)
break
case "4": //"周四":
weekdays = append(weekdays, time.Thursday)
break
case "5": //"周五":
weekdays = append(weekdays, time.Friday)
break
case "6": //"周六":
weekdays = append(weekdays, time.Saturday)
break
}
}
return weekdays
}
// 检查时间是否跨天
func (productCalendar *ProductCalendar) CheckOverDay(t time.Time) (bool, error) {
th := t.Hour()
inHour, parseInHourErr := strconv.Atoi(strings.Split(productCalendar.InWorkAt, ":")[0])
if parseInHourErr != nil {
return false, parseInHourErr
}
outHour, parseOutHourErr := strconv.Atoi(strings.Split(productCalendar.OutWorkAt, ":")[0])
if parseOutHourErr != nil {
return false, parseOutHourErr
}
if inHour < outHour {
return false, nil // eg: 7:00 17:00 t 9:00
}
if th >= inHour && th < 24 {
return false, nil // eg: 7:00 24:00 t 20:00
}
if th >= 0 && th < outHour {
return true, nil
}
return false, nil
}
... ...
... ... @@ -168,6 +168,23 @@ func FindGroupMembers(productGroupRepository domain.ProductGroupRepository, comp
return result, keyFunc
}
// 查询组成员属于的分组
func FindMemberBelongToProductGroup(productGroupRepository domain.ProductGroupRepository, companyId, orgId int, workStationId string, member *domain.User) (*domain.ProductGroup, error) {
_, groups, err := productGroupRepository.Find(map[string]interface{}{"companyId": companyId, "orgId": orgId, "workStationId": workStationId})
if err != nil {
return nil, err
}
for i := range groups {
for j := range groups[i].GroupMembers {
u := groups[i].GroupMembers[j]
if u.UserId == member.UserId {
return groups[i], nil
}
}
}
return nil, nil
}
// 个人生产记录统计
func (ptr *PGProductRecordService) personalProductStatics(productPlan *domain.ProductPlan, productRecord *domain.ProductRecord) (interface{}, error) {
var (
... ...
... ... @@ -21,9 +21,10 @@ func (ptr *PGWorkerAttendanceReportService) Report(cid, oid int, report *domain.
var (
attendanceRecordDao, _ = dao.NewAttendanceRecordDao(ptr.transactionContext)
attendanceRecordRepository, _ = repository.NewProductAttendanceRecordRepository(ptr.transactionContext)
productGroupRepository, _ = repository.NewProductGroupRepository(ptr.transactionContext)
productCalendarRepository, _ = repository.NewProductCalendarRepository(ptr.transactionContext)
isSignIn = true
record *domain.ProductAttendanceRecord
//workStationId string //具体工位
workStation *domain.WorkStation
attendanceType int = domain.ParticipateSupport
worker *domain.User
... ... @@ -37,7 +38,6 @@ func (ptr *PGWorkerAttendanceReportService) Report(cid, oid int, report *domain.
var (
device *domain.Device
err error
productGroupRepository, _ = repository.NewProductGroupRepository(ptr.transactionContext)
groupId = 0
groupName = ""
)
... ... @@ -58,15 +58,17 @@ func (ptr *PGWorkerAttendanceReportService) Report(cid, oid int, report *domain.
return nil, err
}
groupMembers, groupMembersKeyFunc := FindGroupMembers(productGroupRepository, cid, oid, workStation.WorkStationId)
if v, ok := groupMembers[groupMembersKeyFunc(worker.UserId)]; ok {
var productCalendar *domain.ProductCalendar
productGroup, _ := FindMemberBelongToProductGroup(productGroupRepository, cid, oid, workStation.WorkStationId, worker)
if productGroup != nil {
attendanceType = domain.ParticipateNormal
groupId = v.GroupId
groupName = v.GroupName
groupId = productGroup.ProductGroupId
groupName = productGroup.GroupName
productCalendar, _ = productCalendarRepository.FindOne(map[string]interface{}{"companyId": cid, "orgId": oid, "workStationId": workStation.WorkStationId})
}
beginTime := utils.GetZeroTime(report.ActionTime)
endTime := time.Now()
beginTime := report.ActionTime.Add(-time.Hour * 13)
endTime := report.ActionTime
_, records, _ := attendanceRecordDao.WorkerAttendanceRecords(cid, oid, worker.UserId, "", beginTime, endTime)
for i := 0; i < len(records); i++ {
r := records[i]
... ... @@ -76,7 +78,7 @@ func (ptr *PGWorkerAttendanceReportService) Report(cid, oid int, report *domain.
if !utils.TimeIsZero(r.SignIn) && utils.TimeIsZero(r.SignOut) {
if utils.TimeAfterEqual(report.ActionTime, r.SignIn) {
r.SignOut = report.ActionTime
r.WorkTimeBefore = r.ComputeWorkTimeBefore()
r.WorkTimeBefore = r.ComputeWorkTimeBefore(productCalendar)
log.Logger.Debug(fmt.Sprintf("【考勤汇报】 用户:%v(%v) 在其他工段打卡 下线当前工段:%v 签退 %v", worker.UserName, worker.UserId, r.WorkStation.SectionName, report))
if _, err = attendanceRecordRepository.Save(r); err != nil {
return nil, err
... ... @@ -148,10 +150,11 @@ func (ptr *PGWorkerAttendanceReportService) Report(cid, oid int, report *domain.
ProductGroupId: groupId,
}),
}
record.SetProductTimeByProductCalendar(productCalendar)
log.Logger.Debug(fmt.Sprintf("【考勤汇报】 用户:%v(%v) 签到 %v", worker.UserName, worker.UserId, report))
} else {
record.SignOut = report.ActionTime
record.WorkTimeBefore = record.ComputeWorkTimeBefore()
record.WorkTimeBefore = record.ComputeWorkTimeBefore(productCalendar)
log.Logger.Debug(fmt.Sprintf("【考勤汇报】 用户:%v(%v) 签退 %v", worker.UserName, worker.UserId, report))
}
... ...
... ... @@ -31,7 +31,7 @@ func (ptr *PGWorkshopWorkTimeStaticService) WorkshopWorkTimeStatic(productRecord
CompanyId: productRecord.CompanyId,
OrgId: productRecord.OrgId,
Ext: productRecord.Ext,
RecordDate: utils.GetZeroTime(productRecord.SignIn),
RecordDate: utils.GetZeroTime(productRecord.ProductTime()), // utils.GetZeroTime(productRecord.SignIn),
WorkshopWorkTimeRecordInfo: &domain.WorkshopWorkTimeRecordInfo{},
}
}
... ...
... ... @@ -6,7 +6,6 @@ import (
"github.com/go-redis/redis"
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/constant"
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/domain"
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/log"
"time"
)
... ... @@ -15,7 +14,7 @@ func GetDeviceDailyRunningRecord(t time.Time, deviceCode string) (*domain.Device
client := GetRedis()
key := DeviceDailyRunningRecordKey(t, deviceCode)
record, err := getDeviceDailyRunningRecord(client, key)
log.Logger.Debug(fmt.Sprintf("Redis Device:%v GET Key:%v Value:%v", deviceCode, key, record))
//log.Logger.Debug(fmt.Sprintf("Redis Device:%v GET Key:%v Value:%v", deviceCode, key, record))
return record, err
}
... ... @@ -50,7 +49,7 @@ func SaveDeviceDailyRunningRecordByKey(key string, record *domain.DeviceDailyRun
if err != nil {
return err
}
log.Logger.Debug(fmt.Sprintf("Redis Device:%v SET Key:%v Value:%v", record.DeviceCode, key, record))
//log.Logger.Debug(fmt.Sprintf("Redis Device:%v SET Key:%v Value:%v", record.DeviceCode, key, record))
result := client.Set(key, recordData, time.Hour*24*5)
_, err = result.Result()
return err
... ...
... ... @@ -133,6 +133,9 @@ func (repository *ProductCalendarRepository) FindOne(queryOptions map[string]int
tx := repository.transactionContext.PgTx
productCalendarModel := new(models.ProductCalendar)
query := sqlbuilder.BuildQuery(tx.Model(productCalendarModel), queryOptions)
query.SetWhereByQueryOption("company_id = ?", "companyId")
query.SetWhereByQueryOption("org_id = ?", "orgId")
query.SetWhereByQueryOption("work_station->>'workStationId'=?", "workStationId")
query.SetWhereByQueryOption("product_calendar.product_calendar_id = ?", "productCalendarId")
if v, ok := queryOptions["includeDeleted"]; ok && v.(bool) {
query.AllWithDeleted()
... ...
... ... @@ -123,6 +123,8 @@ func (repository *ProductGroupRepository) FindOne(queryOptions map[string]interf
tx := repository.transactionContext.PgTx
productGroupModel := new(models.ProductGroup)
query := sqlbuilder.BuildQuery(tx.Model(productGroupModel), queryOptions)
query.SetWhereByQueryOption("company_id = ?", "companyId")
query.SetWhereByQueryOption("org_id = ?", "orgId")
query.SetWhereByQueryOption("product_group.product_group_id = ?", "productGroupId")
query.SetWhereByQueryOption("group_name=?", "groupName")
query.SetWhereByQueryOption("work_station->>'workStationId'=?", "workStationId")
... ...