Change logic for due dates. Previosuly they were 15 days after the first days of the quarters last month. Now, due dates are 15 days after the last day of the quarters last month.
Этот коммит содержится в:
@@ -16,7 +16,6 @@ import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v6/model"
|
||||
"github.com/mattermost/mattermost-server/v6/shared/mlog"
|
||||
@@ -35,11 +34,6 @@ hwIDAQAB
|
||||
|
||||
var LicenseValidator LicenseValidatorIface
|
||||
|
||||
const trueUpReviewDueDay = 15
|
||||
const businessQuarterStep = 3
|
||||
const day = time.Hour * 24
|
||||
const week = day * 7
|
||||
|
||||
func init() {
|
||||
if LicenseValidator == nil {
|
||||
LicenseValidator = &LicenseValidatorImpl{}
|
||||
@@ -230,30 +224,3 @@ func GetSanitizedClientLicense(l map[string]string) map[string]string {
|
||||
|
||||
return sanitizedLicense
|
||||
}
|
||||
|
||||
func GetNextTrueUpReviewDueDate(now time.Time) time.Time {
|
||||
quaterEndMonths := []time.Month{time.March, time.June, time.September, time.December}
|
||||
|
||||
var nextQuarterEndMonth time.Month = time.March
|
||||
for _, month := range quaterEndMonths {
|
||||
if now.Month() <= month && now.Day() <= trueUpReviewDueDay {
|
||||
nextQuarterEndMonth = month
|
||||
break
|
||||
} else if now.Month() <= month && now.Day() > trueUpReviewDueDay {
|
||||
nextQuarterEndMonth = month + businessQuarterStep
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return time.Date(now.Year(), nextQuarterEndMonth, trueUpReviewDueDay, 0, 0, 0, 0, now.Location())
|
||||
}
|
||||
|
||||
func IsTrueUpReviewDueDateWithinTheNextTwoWeeks(now time.Time, dueDate time.Time) bool {
|
||||
dueDateWindow := dueDate.Add(-(week * 2))
|
||||
|
||||
if now.Before(dueDateWindow) || now.After(dueDate) {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -8,7 +8,6 @@ import (
|
||||
"encoding/base64"
|
||||
"os"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
@@ -92,114 +91,3 @@ func TestGetLicenseFileFromDisk(t *testing.T) {
|
||||
assert.False(t, success, "should have been an invalid file")
|
||||
})
|
||||
}
|
||||
|
||||
func TestGetNextTrueUpReviewDueDate(t *testing.T) {
|
||||
t.Run("Due date always falls on the 15th", func(t *testing.T) {
|
||||
// Before the 15th
|
||||
now := time.Date(2022, 12, 14, 0, 0, 0, 0, time.Local)
|
||||
due := GetNextTrueUpReviewDueDate(now)
|
||||
assert.Equal(t, due.Day(), trueUpReviewDueDay)
|
||||
|
||||
// On the 15th
|
||||
now = time.Date(2022, 12, 15, 0, 0, 0, 0, time.Local)
|
||||
due = GetNextTrueUpReviewDueDate(now)
|
||||
assert.Equal(t, due.Day(), trueUpReviewDueDay)
|
||||
|
||||
// After the 15th
|
||||
now = time.Date(2022, 12, 16, 0, 0, 0, 0, time.Local)
|
||||
due = GetNextTrueUpReviewDueDate(now)
|
||||
assert.Equal(t, due.Day(), trueUpReviewDueDay)
|
||||
})
|
||||
|
||||
t.Run("Due date will always be in next quarter if the current date is past the 15th", func(t *testing.T) {
|
||||
now := time.Date(2022, time.March, 16, 0, 0, 0, 0, time.Local)
|
||||
due := GetNextTrueUpReviewDueDate(now)
|
||||
assert.Equal(t, time.June, due.Month())
|
||||
|
||||
now = time.Date(2022, time.June, 16, 0, 0, 0, 0, time.Local)
|
||||
due = GetNextTrueUpReviewDueDate(now)
|
||||
assert.Equal(t, time.September, due.Month())
|
||||
|
||||
now = time.Date(2022, time.September, 16, 0, 0, 0, 0, time.Local)
|
||||
due = GetNextTrueUpReviewDueDate(now)
|
||||
assert.Equal(t, time.December, due.Month())
|
||||
|
||||
now = time.Date(2022, time.December, 16, 0, 0, 0, 0, time.Local)
|
||||
due = GetNextTrueUpReviewDueDate(now)
|
||||
assert.Equal(t, time.March, due.Month())
|
||||
})
|
||||
|
||||
t.Run("Due date will always be in the current quarter if the current date is before or on the 15th", func(t *testing.T) {
|
||||
now := time.Date(2022, time.March, 15, 0, 0, 0, 0, time.Local)
|
||||
due := GetNextTrueUpReviewDueDate(now)
|
||||
assert.Equal(t, time.March, due.Month())
|
||||
|
||||
now = time.Date(2022, time.June, 15, 0, 0, 0, 0, time.Local)
|
||||
due = GetNextTrueUpReviewDueDate(now)
|
||||
assert.Equal(t, time.June, due.Month())
|
||||
|
||||
now = time.Date(2022, time.September, 14, 0, 0, 0, 0, time.Local)
|
||||
due = GetNextTrueUpReviewDueDate(now)
|
||||
assert.Equal(t, time.September, due.Month())
|
||||
|
||||
now = time.Date(2022, time.December, 14, 0, 0, 0, 0, time.Local)
|
||||
due = GetNextTrueUpReviewDueDate(now)
|
||||
assert.Equal(t, time.December, due.Month())
|
||||
})
|
||||
|
||||
t.Run("Due date will be in the next year if the next quarter is not within the current year", func(t *testing.T) {
|
||||
now := time.Date(2022, time.December, 18, 0, 0, 0, 0, time.Local)
|
||||
due := GetNextTrueUpReviewDueDate(now)
|
||||
assert.Equal(t, time.March, due.Month())
|
||||
assert.Equal(t, 2023, due.Year())
|
||||
})
|
||||
}
|
||||
|
||||
func TestIsTrueUpReviewDueDateWithinTheNextTwoWeeks(t *testing.T) {
|
||||
t.Run("Ensure a date within two weeks before the due date returns true", func(t *testing.T) {
|
||||
// 1 Day before the due date
|
||||
now := time.Date(2022, time.December, 14, 0, 0, 0, 0, time.Local)
|
||||
// Due date is December 15th, 2022
|
||||
due := GetNextTrueUpReviewDueDate(now)
|
||||
|
||||
res := IsTrueUpReviewDueDateWithinTheNextTwoWeeks(now, due)
|
||||
assert.True(t, res)
|
||||
})
|
||||
|
||||
t.Run("Ensure a date that is more than two weeks before the due date returns false", func(t *testing.T) {
|
||||
// 15 Days before the due date
|
||||
now := time.Date(2022, time.November, 30, 0, 0, 0, 0, time.Local)
|
||||
// Due date is December 15th, 2022
|
||||
due := GetNextTrueUpReviewDueDate(now)
|
||||
|
||||
res := IsTrueUpReviewDueDateWithinTheNextTwoWeeks(now, due)
|
||||
assert.False(t, res)
|
||||
})
|
||||
|
||||
t.Run("Ensure a date that past the due date returns false", func(t *testing.T) {
|
||||
now := time.Date(2022, time.December, 16, 0, 0, 0, 0, time.Local)
|
||||
|
||||
// Due date is December 15th, 2022
|
||||
dueNow := time.Date(2022, time.December, 15, 0, 0, 0, 0, time.Local)
|
||||
due := GetNextTrueUpReviewDueDate(dueNow)
|
||||
|
||||
res := IsTrueUpReviewDueDateWithinTheNextTwoWeeks(now, due)
|
||||
assert.False(t, res)
|
||||
})
|
||||
|
||||
t.Run("Ensure a date that is on the due date returns true", func(t *testing.T) {
|
||||
now := time.Date(2022, time.December, 15, 0, 0, 0, 0, time.Local)
|
||||
due := GetNextTrueUpReviewDueDate(now)
|
||||
|
||||
res := IsTrueUpReviewDueDateWithinTheNextTwoWeeks(now, due)
|
||||
assert.True(t, res)
|
||||
})
|
||||
|
||||
t.Run("Ensure a date that is on the first day of the due date window returns true", func(t *testing.T) {
|
||||
now := time.Date(2022, time.December, 1, 0, 0, 0, 0, time.Local)
|
||||
due := GetNextTrueUpReviewDueDate(now)
|
||||
|
||||
res := IsTrueUpReviewDueDateWithinTheNextTwoWeeks(now, due)
|
||||
assert.True(t, res)
|
||||
})
|
||||
}
|
||||
|
||||
85
utils/true_up.go
Обычный файл
85
utils/true_up.go
Обычный файл
@@ -0,0 +1,85 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package utils
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
|
||||
const trueUpReviewDueDay = 15
|
||||
const day = time.Hour * 24
|
||||
const week = day * 7
|
||||
|
||||
type DueDateWindow struct {
|
||||
Start time.Time
|
||||
End time.Time
|
||||
}
|
||||
|
||||
func GetNextTrueUpReviewDueDate(now time.Time) time.Time {
|
||||
nowYear := now.Year()
|
||||
nowMonth := now.Month()
|
||||
nowDay := now.Day()
|
||||
finalQuarterYear := nowYear
|
||||
if nowMonth >= time.October && nowMonth <= time.December {
|
||||
finalQuarterYear = nowYear + 1
|
||||
}
|
||||
trueUpSubmissionWindows := []DueDateWindow{
|
||||
{
|
||||
Start: time.Date(now.Year(), time.January, 16, 0, 0, 0, 0, now.Location()),
|
||||
End: time.Date(now.Year(), time.April, 15, 0, 0, 0, 0, now.Location()),
|
||||
},
|
||||
{
|
||||
Start: time.Date(now.Year(), time.April, 16, 0, 0, 0, 0, now.Location()),
|
||||
End: time.Date(now.Year(), time.July, 15, 0, 0, 0, 0, now.Location()),
|
||||
},
|
||||
{
|
||||
Start: time.Date(now.Year(), time.July, 16, 0, 0, 0, 0, now.Location()),
|
||||
End: time.Date(now.Year(), time.October, 15, 0, 0, 0, 0, now.Location()),
|
||||
},
|
||||
{
|
||||
Start: time.Date(now.Year(), time.October, 16, 0, 0, 0, 0, now.Location()),
|
||||
End: time.Date(finalQuarterYear, time.January, 15, 0, 0, 0, 0, now.Location()),
|
||||
},
|
||||
}
|
||||
|
||||
for _, window := range trueUpSubmissionWindows {
|
||||
withinWindow := false
|
||||
// Our due dates "wrap" around, so we'll need to check the months different. Since January = 1 and December = 12, the checks
|
||||
// for the current month being greater or equal to the start month and less than or equal to the end month will not work.
|
||||
if window.End.Month() == time.January {
|
||||
withinWindow = (nowMonth != time.January && nowMonth >= window.Start.Month()) || nowMonth == window.End.Month()
|
||||
} else {
|
||||
withinWindow = nowMonth >= window.Start.Month() && nowMonth <= window.End.Month()
|
||||
fmt.Printf("now month: %s, window start month: %s, window end month: %s\n", now.Format("Jan"), window.Start.Format("Jan"), window.End.Format("Jan"))
|
||||
}
|
||||
|
||||
// Only check the days if the current month is equal to the start or end months.
|
||||
// The dates of the middle month(s) don't matter so much.
|
||||
isFirstMonth := nowMonth == window.Start.Month()
|
||||
if isFirstMonth {
|
||||
withinWindow = withinWindow && nowDay >= window.Start.Day()
|
||||
}
|
||||
isFinalMonth := nowMonth == window.End.Month()
|
||||
if isFinalMonth {
|
||||
withinWindow = withinWindow && nowDay <= window.End.Day()
|
||||
}
|
||||
|
||||
if withinWindow {
|
||||
return window.End
|
||||
}
|
||||
}
|
||||
|
||||
return trueUpSubmissionWindows[0].End
|
||||
}
|
||||
|
||||
func IsTrueUpReviewDueDateWithinTheNext30Days(now time.Time, dueDate time.Time) bool {
|
||||
dueDateWindow := dueDate.Add(-day * 30)
|
||||
|
||||
if now.Before(dueDateWindow) || now.After(dueDate) {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
125
utils/true_up_test.go
Обычный файл
125
utils/true_up_test.go
Обычный файл
@@ -0,0 +1,125 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package utils
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestGetNextTrueUpReviewDueDate(t *testing.T) {
|
||||
t.Run("Due date always falls on the 15th", func(t *testing.T) {
|
||||
// Before the 15th
|
||||
now := time.Date(2022, 12, 14, 0, 0, 0, 0, time.Local)
|
||||
due := GetNextTrueUpReviewDueDate(now)
|
||||
assert.Equal(t, due.Day(), trueUpReviewDueDay)
|
||||
|
||||
// On the 15th
|
||||
now = time.Date(2022, 12, 15, 0, 0, 0, 0, time.Local)
|
||||
due = GetNextTrueUpReviewDueDate(now)
|
||||
assert.Equal(t, due.Day(), trueUpReviewDueDay)
|
||||
|
||||
// After the 15th
|
||||
now = time.Date(2022, 12, 16, 0, 0, 0, 0, time.Local)
|
||||
due = GetNextTrueUpReviewDueDate(now)
|
||||
assert.Equal(t, due.Day(), trueUpReviewDueDay)
|
||||
})
|
||||
|
||||
t.Run("Due date will always be in next quarter if the current date is past the 15th", func(t *testing.T) {
|
||||
now := time.Date(2022, time.March, 16, 0, 0, 0, 0, time.Local)
|
||||
due := GetNextTrueUpReviewDueDate(now)
|
||||
assert.Equal(t, time.April, due.Month())
|
||||
|
||||
now = time.Date(2022, time.June, 16, 0, 0, 0, 0, time.Local)
|
||||
due = GetNextTrueUpReviewDueDate(now)
|
||||
assert.Equal(t, time.July, due.Month())
|
||||
|
||||
now = time.Date(2022, time.September, 16, 0, 0, 0, 0, time.Local)
|
||||
due = GetNextTrueUpReviewDueDate(now)
|
||||
assert.Equal(t, time.October, due.Month())
|
||||
|
||||
now = time.Date(2022, time.December, 16, 0, 0, 0, 0, time.Local)
|
||||
due = GetNextTrueUpReviewDueDate(now)
|
||||
assert.Equal(t, time.January, due.Month())
|
||||
})
|
||||
|
||||
t.Run("Due date will always be in the current quarter if the current date is before or on the 15th", func(t *testing.T) {
|
||||
now := time.Date(2022, time.April, 15, 0, 0, 0, 0, time.Local)
|
||||
due := GetNextTrueUpReviewDueDate(now)
|
||||
assert.Equal(t, time.April, due.Month())
|
||||
|
||||
now = time.Date(2022, time.July, 15, 0, 0, 0, 0, time.Local)
|
||||
due = GetNextTrueUpReviewDueDate(now)
|
||||
assert.Equal(t, time.July, due.Month())
|
||||
|
||||
now = time.Date(2022, time.October, 14, 0, 0, 0, 0, time.Local)
|
||||
due = GetNextTrueUpReviewDueDate(now)
|
||||
assert.Equal(t, time.October, due.Month())
|
||||
|
||||
now = time.Date(2022, time.January, 14, 0, 0, 0, 0, time.Local)
|
||||
due = GetNextTrueUpReviewDueDate(now)
|
||||
assert.Equal(t, time.January, due.Month())
|
||||
})
|
||||
|
||||
t.Run("Due date will be in the next year if the next quarter is not within the current year", func(t *testing.T) {
|
||||
now := time.Date(2022, time.October, 21, 0, 0, 0, 0, time.Local)
|
||||
due := GetNextTrueUpReviewDueDate(now)
|
||||
assert.Equal(t, time.January, due.Month())
|
||||
assert.Equal(t, 2023, due.Year())
|
||||
})
|
||||
}
|
||||
|
||||
func TestIsTrueUpReviewDueDateWithinTheNext15Days(t *testing.T) {
|
||||
t.Run("Ensure a date within 30 days before the due date returns true", func(t *testing.T) {
|
||||
// 1 Day before the due date
|
||||
now := time.Date(2022, time.March, 16, 0, 0, 0, 0, time.Local)
|
||||
// Due date is December 15th, 2022
|
||||
due := GetNextTrueUpReviewDueDate(now)
|
||||
|
||||
res := IsTrueUpReviewDueDateWithinTheNext30Days(now, due)
|
||||
assert.True(t, res)
|
||||
})
|
||||
|
||||
t.Run("Ensure a date that is more than two weeks before the due date returns false", func(t *testing.T) {
|
||||
// 15 Days before the due date
|
||||
now := time.Date(2022, time.October, 16, 0, 0, 0, 0, time.Local)
|
||||
// Due date is December 15th, 2022
|
||||
due := GetNextTrueUpReviewDueDate(now)
|
||||
|
||||
res := IsTrueUpReviewDueDateWithinTheNext30Days(now, due)
|
||||
assert.False(t, res)
|
||||
})
|
||||
|
||||
t.Run("Ensure a date that is past the due date returns false", func(t *testing.T) {
|
||||
now := time.Date(2022, time.April, 15, 0, 0, 0, 0, time.Local)
|
||||
|
||||
// Due date is April 16th, 2022
|
||||
dueNow := time.Date(2022, time.April, 16, 0, 0, 0, 0, time.Local)
|
||||
due := GetNextTrueUpReviewDueDate(dueNow)
|
||||
|
||||
res := IsTrueUpReviewDueDateWithinTheNext30Days(now, due)
|
||||
assert.False(t, res)
|
||||
})
|
||||
|
||||
t.Run("Ensure a date that is on the due date returns true", func(t *testing.T) {
|
||||
now := time.Date(2022, time.January, 15, 0, 0, 0, 0, time.Local)
|
||||
due := GetNextTrueUpReviewDueDate(now)
|
||||
fmt.Printf("\n\ndue date: %s\n\n", due.Format("2006-Jan-02"))
|
||||
fmt.Printf("\n\nnow: %s\n\n", now.Format("2006-Jan-02"))
|
||||
|
||||
res := IsTrueUpReviewDueDateWithinTheNext30Days(now, due)
|
||||
assert.True(t, res)
|
||||
})
|
||||
|
||||
t.Run("Ensure a date that is on the first day of the due date window returns true", func(t *testing.T) {
|
||||
now := time.Date(2022, time.December, 16, 0, 0, 0, 0, time.Local)
|
||||
due := GetNextTrueUpReviewDueDate(now)
|
||||
|
||||
res := IsTrueUpReviewDueDateWithinTheNext30Days(now, due)
|
||||
assert.True(t, res)
|
||||
})
|
||||
}
|
||||
Ссылка в новой задаче
Block a user