This repository has been archived by the owner on Nov 9, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathtimeentry.go
113 lines (97 loc) · 2.82 KB
/
timeentry.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
package api
import (
"encoding/json"
"fmt"
"log"
"net/url"
"strconv"
"strings"
"time"
)
// TimeEntry maps the JSON returned by TimeCamp API /entries.
//
// API docs: https://github.com/timecamp/timecamp-api/blob/master/sections/time-entries.md
// Created with https://mholt.github.io/json-to-go/
type TimeEntry struct {
ID int `json:"id"`
Duration string `json:"duration"`
UserID string `json:"user_id"`
UserName string `json:"user_name"`
TaskID string `json:"task_id"`
LastModify string `json:"last_modify"`
Date string `json:"date"`
StartTime string `json:"start_time"`
EndTime string `json:"end_time"`
Locked string `json:"locked"`
Name string `json:"name"`
AddonsExternalID string `json:"addons_external_id"`
Billable int `json:"billable"`
InvoiceID string `json:"invoiceId"`
Color string `json:"color"`
Description string `json:"description"`
}
func (t TimeEntry) TaskIdInt() int {
id, _ := strconv.Atoi(t.TaskID)
return id
}
func (e TimeEntry) DurationParsed() (time.Duration, error) {
secs := strings.Join([]string{e.Duration, "s"}, "")
dur, err := time.ParseDuration(secs)
if err != nil {
return 0, err
}
return dur, nil
}
func (e TimeEntry) DateParsed() time.Time {
date, err := time.Parse(DateFormat, e.Date)
if err != nil {
log.Fatal("could not parse entry date:", e.Date)
}
return date
}
func (e TimeEntry) HasDescription() bool {
return len(strings.Trim(e.Description, " ")) > 0
}
func (e TimeEntry) IsBillable() bool {
return e.Billable > 0
}
// TimeEntryParams query parameters.
type TimeEntryParams struct {
From time.Time
To time.Time
Tasks []Task
}
// GetTimeEntries wraps the "GET /entries" api endpoint.
// If params.Tasks is nil / empty, all tasks' entries are returned.
func GetTimeEntries(con Connection, params TimeEntryParams) ([]TimeEntry, error) {
queryUrl, err := timeEntryUrl(con, params)
if err != nil {
return nil, err
}
data, err := httpGet(queryUrl)
if err != nil {
return nil, err
}
var result []TimeEntry
err = json.Unmarshal(data, &result)
if err != nil {
return nil, err
}
return result, nil
}
func timeEntryUrl(connection Connection, params TimeEntryParams) (string, error) {
if !params.From.Before(params.To) {
return "", fmt.Errorf("GetTimeEntries: From date must be before To date")
}
var taskIds []string
for _, task := range params.Tasks {
taskIds = append(taskIds, strconv.FormatInt(int64(task.TaskID), 10))
}
queryUrl, err := url.Parse(connection.ApiUrl + "/entries/format/json/api_token/" + connection.Token + "/from/" +
params.From.Format(DateFormat) + "/to/" + params.To.Format(DateFormat) +
"/task_ids/" + strings.Join(taskIds, ","))
if err != nil {
return "", err
}
return queryUrl.String(), err
}