Fix monthly recurring transactions not being created when the year changes
The previous implementation only checked that at least one month had passed between the last run date and now by subtracting the ordinal values. If it were February (month 2) and the previous run date were in January (month 1), then 2 - 1 would equal 1, so it would have been one month since the previous run and we would create the recurring transaction. If it were December however (month 12), the following month would be January (month 1), and 1 - 12 would be -11, so it would appear that we had already created a transaction 11 months in the future. The new implementation also takes the year into account to avoid this situation.
This commit is contained in:
parent
f8c970eb68
commit
2a7d674204
2 changed files with 45 additions and 20 deletions
|
@ -40,7 +40,8 @@ class RecurringTransactionProcessingJob(
|
|||
is Frequency.Monthly -> {
|
||||
it.lastRun?.let { last ->
|
||||
val zonedLastRun = last.atZone(ZoneId.of("UTC"))
|
||||
if (zonedNow.monthValue - zonedLastRun.monthValue < it.frequency.count)
|
||||
val monthsPassed = ((zonedNow.year * 12) + zonedNow.monthValue) - ((zonedLastRun.year * 12) + zonedLastRun.monthValue)
|
||||
if (monthsPassed < it.frequency.count)
|
||||
return@forEach
|
||||
}
|
||||
val frequency = (it.frequency as Frequency.Monthly).dayOfMonth
|
||||
|
@ -63,7 +64,6 @@ class RecurringTransactionProcessingJob(
|
|||
return@forEach
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
is Frequency.Yearly -> {
|
||||
|
|
|
@ -231,19 +231,19 @@ class RecurringTransactionProcessingJobTest {
|
|||
fun `monthly transactions are created every last friday`() = runBlockingTest {
|
||||
val start = Instant.parse("1970-01-01T00:00:00Z")
|
||||
recurringTransactionRepository.save(
|
||||
RecurringTransaction(
|
||||
title = "Monthly transaction",
|
||||
amount = 123,
|
||||
frequency = Frequency.Monthly(
|
||||
1,
|
||||
DayOfMonth.positionalDayOfWeek(Position.LAST, DayOfWeek.FRIDAY),
|
||||
Time(9, 0, 0)
|
||||
),
|
||||
expense = true,
|
||||
start = start,
|
||||
createdBy = "tester",
|
||||
budgetId = "budgetId"
|
||||
)
|
||||
RecurringTransaction(
|
||||
title = "Monthly transaction",
|
||||
amount = 123,
|
||||
frequency = Frequency.Monthly(
|
||||
1,
|
||||
DayOfMonth.positionalDayOfWeek(Position.LAST, DayOfWeek.FRIDAY),
|
||||
Time(9, 0, 0)
|
||||
),
|
||||
expense = true,
|
||||
start = start,
|
||||
createdBy = "tester",
|
||||
budgetId = "budgetId"
|
||||
)
|
||||
)
|
||||
loopFor(start, 120)
|
||||
val createdTransactions = transactionRepository.findAll()
|
||||
|
@ -254,15 +254,40 @@ class RecurringTransactionProcessingJobTest {
|
|||
assertEquals("1970-04-24T09:00:00Z", createdTransactions[3].date.toString())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `monthly transactions are created in the new year`() = runBlockingTest {
|
||||
val start = Instant.parse("1971-01-01T00:00:00Z")
|
||||
recurringTransactionRepository.save(
|
||||
RecurringTransaction(
|
||||
title = "Monthly transaction",
|
||||
amount = 123,
|
||||
frequency = Frequency.Monthly(
|
||||
1,
|
||||
DayOfMonth.day(1),
|
||||
Time(9, 0, 0)
|
||||
),
|
||||
expense = true,
|
||||
start = start,
|
||||
createdBy = "tester",
|
||||
budgetId = "budgetId",
|
||||
lastRun = Instant.parse("1970-12-01T09:00:00Z")
|
||||
)
|
||||
)
|
||||
loopFor(start, 1)
|
||||
val createdTransactions = transactionRepository.findAll()
|
||||
assertEquals(1, createdTransactions.size)
|
||||
assertEquals("1971-01-01T09:00:00Z", createdTransactions[0].date.toString())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `yearly transactions are created every march 31st`() = runBlockingTest {
|
||||
val start = Instant.parse("1970-01-01T00:00:00Z")
|
||||
recurringTransactionRepository.save(
|
||||
RecurringTransaction(
|
||||
title = "Yearly transaction",
|
||||
amount = 123,
|
||||
frequency = Frequency.Yearly(1, MonthDay.of(3, 31), Time(9, 0, 0)),
|
||||
expense = true,
|
||||
RecurringTransaction(
|
||||
title = "Yearly transaction",
|
||||
amount = 123,
|
||||
frequency = Frequency.Yearly(1, MonthDay.of(3, 31), Time(9, 0, 0)),
|
||||
expense = true,
|
||||
start = start,
|
||||
createdBy = "tester",
|
||||
budgetId = "budgetId"
|
||||
|
|
Loading…
Reference in a new issue