2023-01-27 17:09:18 +01:00
package database
import (
"strconv"
"time"
"velvettear/worklog/internal/log"
"velvettear/worklog/internal/tools"
"gorm.io/gorm"
)
// exported function(s)
func StartTimestamp ( user string ) ( bool , Timestamp ) {
workday := GetActiveTimestamp ( user )
if workday . ID > 0 {
log . Debug ( "workday for today has already been started" , "id: " + strconv . Itoa ( workday . ID ) , "started: " + tools . TimeToHHMMSS ( workday . Start ) )
return false , workday
}
workday = Timestamp {
User : user ,
Start : time . Now ( ) ,
}
result := connection . Create ( & workday )
success := true
if result . Error != nil {
log . Error ( "encountered an error starting a new workday" , result . Error . Error ( ) )
success = false
} else if result . RowsAffected < 1 {
log . Debug ( "could not start a new workday" )
success = false
}
return success , workday
}
2023-02-01 14:10:00 +01:00
func StopTimestamp ( user string ) ( bool , Timestamp ) {
2023-01-27 17:09:18 +01:00
var timestamp Timestamp
2023-02-01 14:10:00 +01:00
result := connection . Where ( "end = ? and user = ?" , tools . ZeroDate , user ) . Last ( & timestamp )
2023-01-27 17:09:18 +01:00
if result . Error != nil {
2023-02-01 14:10:00 +01:00
log . Error ( "encountered an error selecting the last workday for user '" + user + "'" , result . Error . Error ( ) )
2023-01-27 17:09:18 +01:00
return false , timestamp
}
if timestamp . ID == 0 || ! timestamp . End . Equal ( tools . ZeroDate ) {
2023-02-01 14:10:00 +01:00
log . Debug ( "there is no open workday for user '" + user + "' to stop" )
2023-01-27 17:09:18 +01:00
timestamp . ID = 0
return false , timestamp
}
success := true
timestamp . End = time . Now ( )
result = connection . Save ( & timestamp )
if result . Error != nil {
log . Error ( "encountered an error updating the last workday" , result . Error . Error ( ) )
success = false
} else if result . RowsAffected < 1 {
log . Debug ( "could not stop the last workday" )
success = false
}
return success , timestamp
}
func GetFirstTimestamp ( user string , date time . Time ) Timestamp {
2023-01-30 10:31:47 +01:00
return GetTodaysTimestamp ( user , date , true )
}
func GetLastTimestamp ( user string , date time . Time ) Timestamp {
return GetTodaysTimestamp ( user , date , false )
}
func GetTodaysTimestamp ( user string , date time . Time , first bool ) Timestamp {
2023-01-27 17:09:18 +01:00
var timestamp Timestamp
2023-01-30 10:31:47 +01:00
var where string
var order string
if first {
date = time . Date ( date . Year ( ) , date . Month ( ) , date . Day ( ) , 0 , 0 , 0 , 0 , time . UTC )
order = "asc"
where = "start > ?"
} else {
date = time . Date ( date . Year ( ) , date . Month ( ) , date . Day ( ) , 23 , 59 , 59 , 0 , time . UTC )
order = "desc"
where = "start < ?"
}
connection . Where ( where + " and user = ?" , date , user ) . Order ( "start " + order ) . First ( & timestamp )
2023-01-27 17:09:18 +01:00
return timestamp
}
func GetActiveTimestamp ( user string ) Timestamp {
now := time . Now ( )
todayStart := time . Date ( now . Year ( ) , now . Month ( ) , now . Day ( ) , 0 , 0 , 0 , 0 , time . UTC )
var timestamp Timestamp
connection . Where ( "start > ? and end = ? and user = ?" , todayStart , tools . ZeroDate , user ) . First ( & timestamp )
return timestamp
}
func GetAggregatedTimestamps ( from time . Time , to time . Time , user string ) map [ string ] [ ] Timestamp {
var timestamps [ ] Timestamp
connection . Select ( "id" , "start" , "end" ) . Where ( "start >= ? and end <= ? and end != ? and user = ?" , from , to , tools . ZeroDate , user ) . Order ( "id desc" ) . Find ( & timestamps )
var aggregatedTimestamps = make ( map [ string ] [ ] Timestamp )
for _ , timestamp := range timestamps {
date := tools . TimeToDDMMYYYY ( timestamp . Start )
mapEntry := aggregatedTimestamps [ date ]
mapEntry = append ( mapEntry , timestamp )
aggregatedTimestamps [ date ] = mapEntry
}
return aggregatedTimestamps
}
// struct(s)
type Timestamp struct {
gorm . Model
ID int
User string
Start time . Time
End time . Time
}