support setting the last 1 to 3 days of the month to scheduled transaction frequency

This commit is contained in:
MaysWind
2026-04-13 00:06:45 +08:00
parent 0222f61da6
commit d7151bc7ab
26 changed files with 148 additions and 32 deletions
+10
View File
@@ -727,6 +727,16 @@ func (s *TransactionService) CreateScheduledTransactions(c core.Context, current
continue
}
if template.ScheduledFrequencyType == models.TRANSACTION_SCHEDULE_FREQUENCY_TYPE_MONTHLY {
maxDayInMonth := utils.GetMaxDayOfMonth(currentTime.Year(), currentTime.Month())
for i := 0; i < len(frequencyValues); i++ {
if frequencyValues[i] < 0 {
frequencyValues[i] = int64(maxDayInMonth) + frequencyValues[i] + 1
}
}
}
frequencyValueSet := utils.ToSet(frequencyValues)
templateTimeZone := time.FixedZone("Template Timezone", int(template.ScheduledTimezoneUtcOffset)*60)
transactionUnixTime := todayFirstUnixTimeInUTC + int64(template.ScheduledAt)*60
+6
View File
@@ -286,6 +286,12 @@ func IsUnixTimeEqualsYearAndMonth(unixTime int64, timezone *time.Location, year
return date.Year() == int(year) && int(date.Month()) == int(month)
}
// GetMaxDayOfMonth returns the maximum day of the month for the specified year and month
func GetMaxDayOfMonth(year int, month time.Month) int {
t := time.Date(year, month+1, 0, 0, 0, 0, 0, time.UTC)
return t.Day()
}
// GetTimezoneOffsetMinutes returns offset minutes according specified timezone
func GetTimezoneOffsetMinutes(unixTime int64, timezone *time.Location) int16 {
_, tzOffset := parseFromUnixTime(unixTime).In(timezone).Zone()
+26
View File
@@ -333,6 +333,32 @@ func TestIsUnixTimeEqualsYearAndMonth(t *testing.T) {
assert.Equal(t, false, actualValue)
}
func TestGetMaxDayOfMonth(t *testing.T) {
expectedValue := 31
actualValue := GetMaxDayOfMonth(2023, 1)
assert.Equal(t, expectedValue, actualValue)
expectedValue = 28
actualValue = GetMaxDayOfMonth(2023, 2)
assert.Equal(t, expectedValue, actualValue)
expectedValue = 29
actualValue = GetMaxDayOfMonth(2024, 2)
assert.Equal(t, expectedValue, actualValue)
expectedValue = 30
actualValue = GetMaxDayOfMonth(2023, 4)
assert.Equal(t, expectedValue, actualValue)
expectedValue = 31
actualValue = GetMaxDayOfMonth(2023, 12)
assert.Equal(t, expectedValue, actualValue)
expectedValue = 28
actualValue = GetMaxDayOfMonth(2100, 2)
assert.Equal(t, expectedValue, actualValue)
}
func TestGetTimezoneOffsetMinutes_FixedTimezone(t *testing.T) {
timezone := time.FixedZone("Test Timezone", 120*60)
expectedValue := int16(120)