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 } func StopTimestamp(user string) (bool, Timestamp) { var timestamp Timestamp result := connection.Where("end = ? and user = ?", tools.ZeroDate, user).Last(×tamp) if result.Error != nil { log.Error("encountered an error selecting the last workday for user '"+user+"'", result.Error.Error()) return false, timestamp } if timestamp.ID == 0 || !timestamp.End.Equal(tools.ZeroDate) { log.Debug("there is no open workday for user '" + user + "' to stop") timestamp.ID = 0 return false, timestamp } success := true timestamp.End = time.Now() result = connection.Save(×tamp) 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 { 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 { var timestamp Timestamp 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(×tamp) 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(×tamp) 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(×tamps) 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 }