Skip to content

Commit 1a9629e

Browse files
committed
Simplify handling with custom JSON time
1 parent d97b984 commit 1a9629e

File tree

6 files changed

+46
-58
lines changed

6 files changed

+46
-58
lines changed

.golangci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,6 @@ issues:
137137
linters:
138138
- funlen
139139
- dupl
140-
- path: pkg/apis/team_types.go
140+
- path: pkg/apis/team_methods.go
141141
linters:
142142
- wrapcheck

internal/shiftplan/default_rules.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ func (d *DefaultRule) Match(employee apis.Employee, shifts []apis.Shift, start t
2121
func VacationConflict() *DefaultRule {
2222
return &DefaultRule{
2323
fn: func(e apis.Employee, _ []apis.Shift, start time.Time, end time.Time) bool {
24-
days := e.Vacations()
24+
days := e.VacationDays
2525
for vIdx := range days {
2626
day := days[vIdx]
2727
if (day.After(start) && day.Before(end)) || day.Equal(start) || day.Equal(end) {

internal/shiftplan/default_rules_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ func TestVacationConflict(t *testing.T) {
2121
{
2222
name: "Should detect conflict if employee has holiday between scheduled shift",
2323
args: args{
24-
employee: apis.Employee{ID: "a", Name: "a", VacationDays: []string{"2024-01-01"}},
24+
employee: apis.Employee{ID: "a", Name: "a", VacationDays: vacationDays("2024-01-01")},
2525
start: date("2024-01-01"),
2626
end: date("2024-01-02"),
2727
},
@@ -39,7 +39,7 @@ func TestVacationConflict(t *testing.T) {
3939
{
4040
name: "Should not detect conflict if employee has holiday outside scheduled shift",
4141
args: args{
42-
employee: apis.Employee{ID: "a", Name: "a", VacationDays: []string{"2024-01-03"}},
42+
employee: apis.Employee{ID: "a", Name: "a", VacationDays: vacationDays("2024-01-03")},
4343
start: date("2024-01-01"),
4444
end: date("2024-01-02"),
4545
},

internal/shiftplan/planner_test.go

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ func TestPlanner_Plan(t *testing.T) {
5757
{
5858
name: "Should not schedule Primary on holiday days",
5959
employees: []apis.Employee{
60-
{ID: "a@test.ch", Name: "a", VacationDays: []string{"2020-04-01"}},
60+
{ID: "a@test.ch", Name: "a", VacationDays: vacationDays("2020-04-01")},
6161
{ID: "b@test.ch", Name: "b", VacationDays: nil},
6262
{ID: "c@test.ch", Name: "c", VacationDays: nil},
6363
{ID: "d@test.ch", Name: "d", VacationDays: nil},
@@ -99,7 +99,7 @@ func TestPlanner_Plan(t *testing.T) {
9999
name: "Should not schedule Secondary on holiday days",
100100
employees: []apis.Employee{
101101
{ID: "a@test.ch", Name: "a", VacationDays: nil},
102-
{ID: "b@test.ch", Name: "b", VacationDays: []string{"2020-04-01"}},
102+
{ID: "b@test.ch", Name: "b", VacationDays: vacationDays("2020-04-01")},
103103
{ID: "c@test.ch", Name: "c", VacationDays: nil},
104104
{ID: "d@test.ch", Name: "d", VacationDays: nil},
105105
},
@@ -139,10 +139,10 @@ func TestPlanner_Plan(t *testing.T) {
139139
{
140140
name: "Should return an error if can not find next available duty",
141141
employees: []apis.Employee{
142-
{ID: "a@test.ch", Name: "a", VacationDays: []string{"2020-04-01"}},
143-
{ID: "b@test.ch", Name: "b", VacationDays: []string{"2020-04-01"}},
144-
{ID: "c@test.ch", Name: "c", VacationDays: []string{"2020-04-01"}},
145-
{ID: "d@test.ch", Name: "d", VacationDays: []string{"2020-04-01"}},
142+
{ID: "a@test.ch", Name: "a", VacationDays: vacationDays("2020-04-01")},
143+
{ID: "b@test.ch", Name: "b", VacationDays: vacationDays("2020-04-01")},
144+
{ID: "c@test.ch", Name: "c", VacationDays: vacationDays("2020-04-01")},
145+
{ID: "d@test.ch", Name: "d", VacationDays: vacationDays("2020-04-01")},
146146
},
147147
args: args{
148148
start: date("2020-04-01"),
@@ -156,9 +156,9 @@ func TestPlanner_Plan(t *testing.T) {
156156
name: "Should return an error if can not find next secondary",
157157
employees: []apis.Employee{
158158
{ID: "a@test.ch", Name: "a", VacationDays: nil},
159-
{ID: "b@test.ch", Name: "b", VacationDays: []string{"2020-04-01"}},
160-
{ID: "c@test.ch", Name: "c", VacationDays: []string{"2020-04-01"}},
161-
{ID: "d@test.ch", Name: "d", VacationDays: []string{"2020-04-01"}},
159+
{ID: "b@test.ch", Name: "b", VacationDays: vacationDays("2020-04-01")},
160+
{ID: "c@test.ch", Name: "c", VacationDays: vacationDays("2020-04-01")},
161+
{ID: "d@test.ch", Name: "d", VacationDays: vacationDays("2020-04-01")},
162162
},
163163
args: args{
164164
start: date("2020-04-01"),
@@ -191,3 +191,12 @@ func date(s string) time.Time {
191191

192192
return t
193193
}
194+
195+
func vacationDays(days ...string) []apis.VacationDay {
196+
var tmp = make([]apis.VacationDay, len(days))
197+
for _, day := range days {
198+
tmp = append(tmp, apis.VacationDay{Time: date(day)})
199+
}
200+
201+
return tmp
202+
}

pkg/apis/team_methods.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package apis
2+
3+
import (
4+
"time"
5+
)
6+
7+
func (v *VacationDay) UnmarshalJSON(data []byte) error {
8+
if string(data) == "null" || string(data) == `""` {
9+
return nil
10+
}
11+
12+
t, err := time.Parse(time.DateOnly, string(data))
13+
if err != nil {
14+
return err
15+
}
16+
*v = VacationDay{t}
17+
return nil
18+
}

pkg/apis/team_types.go

Lines changed: 6 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
package apis
22

33
import (
4-
"encoding/json"
5-
"fmt"
64
"time"
75
)
86

@@ -12,49 +10,12 @@ type Team struct {
1210
Employees []Employee `json:"employees"`
1311
}
1412

15-
type Employee struct {
16-
ID EmployeeID `json:"id"`
17-
Name string `json:"name"`
18-
VacationDays []string `json:"vacationDays,omitempty"`
19-
parsedVacations []time.Time
13+
type VacationDay struct {
14+
time.Time
2015
}
2116

22-
func (e *Employee) UnmarshalJSON(data []byte) error {
23-
type Alias Employee
24-
temp := &struct {
25-
*Alias
26-
}{
27-
Alias: (*Alias)(e),
28-
}
29-
30-
if err := json.Unmarshal(data, &temp); err != nil {
31-
return err
32-
}
33-
34-
parsedDay, err := parseDateOnly(e.VacationDays)
35-
if err != nil {
36-
return err
37-
}
38-
e.parsedVacations = parsedDay
39-
40-
return nil
41-
}
42-
43-
func (e *Employee) Vacations() []time.Time {
44-
if len(e.VacationDays) != len(e.parsedVacations) {
45-
e.parsedVacations, _ = parseDateOnly(e.VacationDays)
46-
}
47-
return e.parsedVacations
48-
}
49-
50-
func parseDateOnly(dateStr []string) ([]time.Time, error) {
51-
days := make([]time.Time, len(dateStr))
52-
for idx, day := range dateStr {
53-
t, err := time.Parse(time.DateOnly, day)
54-
if err != nil {
55-
return nil, fmt.Errorf("failed to parse date '%s'", day)
56-
}
57-
days[idx] = t
58-
}
59-
return days, nil
17+
type Employee struct {
18+
ID EmployeeID `json:"id"`
19+
Name string `json:"name"`
20+
VacationDays []VacationDay `json:"vacationDays,omitempty"`
6021
}

0 commit comments

Comments
 (0)