From a88f9ea47b3ddceea6e4b21041e0304ff111d2f8 Mon Sep 17 00:00:00 2001 From: ccremer <github.account@chrigel.net> Date: Wed, 9 Nov 2022 11:05:59 +0100 Subject: [PATCH] Fix saving timezone when updating a payslip Without MarshalJSON for TimeZone, then the field gets serialized as "{}", which Odoo accepts and then also returns this when querying again, causing UnmarshalJSON of the TimeZone to fail again. --- pkg/odoo/timezone.go | 8 ++++++++ pkg/odoo/timezone_test.go | 24 ++++++++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/pkg/odoo/timezone.go b/pkg/odoo/timezone.go index d7df51b..c4777ef 100644 --- a/pkg/odoo/timezone.go +++ b/pkg/odoo/timezone.go @@ -27,6 +27,14 @@ func (tz *TimeZone) UnmarshalJSON(b []byte) error { return nil } +// MarshalJSON implements json.Marshaler. +func (tz *TimeZone) MarshalJSON() ([]byte, error) { + if tz.IsEmpty() || tz.Location() == time.Local { + return []byte(`null`), nil + } + return []byte(fmt.Sprintf(`"%s"`, tz.loc)), nil +} + func (tz *TimeZone) Location() *time.Location { if tz == nil { return nil diff --git a/pkg/odoo/timezone_test.go b/pkg/odoo/timezone_test.go index f952224..9f13ce5 100644 --- a/pkg/odoo/timezone_test.go +++ b/pkg/odoo/timezone_test.go @@ -35,6 +35,30 @@ func TestTimeZone_UnmarshalJSON(t *testing.T) { } } +func TestTimeZone_MarshalJSON(t *testing.T) { + tests := map[string]struct { + givenLocation *time.Location + expectedOutput []byte + }{ + "nil": {givenLocation: nil, expectedOutput: []byte("null")}, + "EuropeZurich": {givenLocation: mustLoadLocation("Europe/Zurich"), expectedOutput: []byte(`"Europe/Zurich"`)}, + "Local": {givenLocation: time.Local, expectedOutput: []byte("null")}, // "Local" isn't recognized by Odoo + "UTC": {givenLocation: time.UTC, expectedOutput: []byte(`"UTC"`)}, + } + for name, tt := range tests { + t.Run(name, func(t *testing.T) { + subject := &TimeZone{loc: tt.givenLocation} + result, err := subject.MarshalJSON() + require.NoError(t, err) + if tt.expectedOutput == nil { + assert.Nil(t, result) + } else { + assert.Equal(t, tt.expectedOutput, result) + } + }) + } +} + func mustLoadLocation(name string) *time.Location { loc, err := time.LoadLocation(name) if err != nil {