Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Lähetetään tulotietomuistutukset vain laskutetaan eVakasta -yksiköiden asiakkaille #6475

Merged
merged 2 commits into from
Mar 6, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,12 @@ import fi.espoo.evaka.serviceneed.ShiftCareType
import fi.espoo.evaka.serviceneed.insertServiceNeed
import fi.espoo.evaka.shared.ChildId
import fi.espoo.evaka.shared.DaycareId
import fi.espoo.evaka.shared.EmployeeId
import fi.espoo.evaka.shared.EvakaUserId
import fi.espoo.evaka.shared.IncomeStatementId
import fi.espoo.evaka.shared.PartnershipId
import fi.espoo.evaka.shared.PersonId
import fi.espoo.evaka.shared.async.AsyncJob
import fi.espoo.evaka.shared.async.AsyncJobRunner
import fi.espoo.evaka.shared.auth.UserRole
import fi.espoo.evaka.shared.auth.AuthenticatedUser
import fi.espoo.evaka.shared.dev.DevCareArea
import fi.espoo.evaka.shared.dev.DevDaycare
import fi.espoo.evaka.shared.dev.DevEmployee
Expand All @@ -45,7 +43,6 @@ import fi.espoo.evaka.shared.domain.DateRange
import fi.espoo.evaka.shared.domain.HelsinkiDateTime
import fi.espoo.evaka.shared.domain.MockEvakaClock
import fi.espoo.evaka.shared.job.ScheduledJobs
import fi.espoo.evaka.shared.security.upsertEmployeeUser
import fi.espoo.evaka.snDaycareContractDays15
import java.math.BigDecimal
import java.time.LocalDate
Expand Down Expand Up @@ -82,8 +79,6 @@ class OutdatedIncomeNotificationsIntegrationTest : FullApplicationTest(resetDbBe
private val fridgeHeadOfChildEmail = "fridge_hoc@example.com"
private lateinit var fridgeHeadOfChildId: PersonId
private lateinit var childId: ChildId
private lateinit var employeeId: EmployeeId
private lateinit var employeeEvakaUserId: EvakaUserId
private lateinit var daycareId: DaycareId

@BeforeEach
Expand Down Expand Up @@ -126,9 +121,6 @@ class OutdatedIncomeNotificationsIntegrationTest : FullApplicationTest(resetDbBe
confirmedBy = null,
confirmedAt = null,
)
employeeId = tx.insert(DevEmployee(roles = setOf(UserRole.SERVICE_WORKER)))
tx.upsertEmployeeUser(employeeId)
employeeEvakaUserId = EvakaUserId(employeeId.raw)
}
}

Expand All @@ -140,7 +132,7 @@ class OutdatedIncomeNotificationsIntegrationTest : FullApplicationTest(resetDbBe
it.insert(
DevIncome(
personId = fridgeHeadOfChildId,
modifiedBy = employeeEvakaUserId,
modifiedBy = AuthenticatedUser.SystemInternalUser.evakaUserId,
validFrom = clock.today().minusMonths(1),
validTo = clock.today(),
)
Expand All @@ -149,7 +141,7 @@ class OutdatedIncomeNotificationsIntegrationTest : FullApplicationTest(resetDbBe
it.insert(
DevIncome(
personId = fridgeHeadOfChildId,
modifiedBy = employeeEvakaUserId,
modifiedBy = AuthenticatedUser.SystemInternalUser.evakaUserId,
validFrom = clock.today().plusDays(1),
validTo = clock.today().plusMonths(6),
)
Expand All @@ -165,7 +157,7 @@ class OutdatedIncomeNotificationsIntegrationTest : FullApplicationTest(resetDbBe
it.insert(
DevIncome(
personId = fridgeHeadOfChildId,
modifiedBy = employeeEvakaUserId,
modifiedBy = AuthenticatedUser.SystemInternalUser.evakaUserId,
validFrom = clock.today().minusMonths(1),
validTo = clock.today().plusWeeks(4),
)
Expand All @@ -180,18 +172,40 @@ class OutdatedIncomeNotificationsIntegrationTest : FullApplicationTest(resetDbBe
)
}

private lateinit var fridgePartnerId: PersonId
@Test
fun `notification is not sent if placement unit is not invoiced by municipality`() {
db.transaction {
it.execute {
sql(
"UPDATE daycare SET invoiced_by_municipality = false WHERE id = ${bind(daycareId)}"
)
}

it.insert(
DevIncome(
personId = fridgeHeadOfChildId,
modifiedBy = AuthenticatedUser.SystemInternalUser.evakaUserId,
validFrom = clock.today().minusMonths(1),
validTo = clock.today().plusWeeks(4),
)
)
}

assertEquals(0, getEmails().size)
assertEquals(0, getIncomeNotifications(fridgeHeadOfChildId).size)
}

@Test
fun `fridge partner expiring income is notified 4 weeks beforehand`() {
val fridgePartner = DevPerson(email = "partner@example.com")

db.transaction {
fridgePartnerId =
it.insert(DevPerson(email = "partner@example.com"), DevPersonType.ADULT)
it.insert(fridgePartner, DevPersonType.ADULT)

it.insert(
DevIncome(
personId = fridgePartnerId,
modifiedBy = employeeEvakaUserId,
personId = fridgePartner.id,
modifiedBy = AuthenticatedUser.SystemInternalUser.evakaUserId,
validFrom = clock.today().minusMonths(1),
validTo = clock.today().plusWeeks(4),
)
Expand All @@ -214,7 +228,7 @@ class OutdatedIncomeNotificationsIntegrationTest : FullApplicationTest(resetDbBe
partnershipId,
2,
1,
fridgePartnerId,
fridgePartner.id,
clock.today(),
clock.today(),
clock.now(),
Expand All @@ -224,23 +238,23 @@ class OutdatedIncomeNotificationsIntegrationTest : FullApplicationTest(resetDbBe

assertEquals(1, getEmails().size)
assertEquals(0, getIncomeNotifications(fridgeHeadOfChildId).size)
assertEquals(1, getIncomeNotifications(fridgePartnerId).size)
assertEquals(1, getIncomeNotifications(fridgePartner.id).size)
assertEquals(
IncomeNotificationType.INITIAL_EMAIL,
getIncomeNotifications(fridgePartnerId)[0].notificationType,
getIncomeNotifications(fridgePartner.id)[0].notificationType,
)
}

@Test
fun `fridge partner with partnership end date as null and expiring income is notified 4 weeks beforehand`() {
val fridgePartner = DevPerson(email = "partner@example.com")
db.transaction {
fridgePartnerId =
it.insert(DevPerson(email = "partner@example.com"), DevPersonType.ADULT)
it.insert(fridgePartner, DevPersonType.ADULT)

it.insert(
DevIncome(
personId = fridgePartnerId,
modifiedBy = employeeEvakaUserId,
personId = fridgePartner.id,
modifiedBy = AuthenticatedUser.SystemInternalUser.evakaUserId,
validFrom = clock.today().minusMonths(1),
validTo = clock.today().plusWeeks(4),
)
Expand All @@ -263,7 +277,7 @@ class OutdatedIncomeNotificationsIntegrationTest : FullApplicationTest(resetDbBe
partnershipId,
2,
1,
fridgePartnerId,
fridgePartner.id,
clock.today(),
null,
clock.now(),
Expand All @@ -273,10 +287,10 @@ class OutdatedIncomeNotificationsIntegrationTest : FullApplicationTest(resetDbBe

assertEquals(1, getEmails().size)
assertEquals(0, getIncomeNotifications(fridgeHeadOfChildId).size)
assertEquals(1, getIncomeNotifications(fridgePartnerId).size)
assertEquals(1, getIncomeNotifications(fridgePartner.id).size)
assertEquals(
IncomeNotificationType.INITIAL_EMAIL,
getIncomeNotifications(fridgePartnerId)[0].notificationType,
getIncomeNotifications(fridgePartner.id)[0].notificationType,
)
}

Expand All @@ -286,7 +300,7 @@ class OutdatedIncomeNotificationsIntegrationTest : FullApplicationTest(resetDbBe
it.insert(
DevIncome(
personId = fridgeHeadOfChildId,
modifiedBy = employeeEvakaUserId,
modifiedBy = AuthenticatedUser.SystemInternalUser.evakaUserId,
validFrom = clock.today().minusMonths(1),
validTo = clock.today().minusDays(2),
)
Expand All @@ -304,7 +318,7 @@ class OutdatedIncomeNotificationsIntegrationTest : FullApplicationTest(resetDbBe
it.insert(
DevIncome(
personId = fridgeHeadOfChildId,
modifiedBy = employeeEvakaUserId,
modifiedBy = AuthenticatedUser.SystemInternalUser.evakaUserId,
validFrom = incomeExpirationDate.minusMonths(1),
validTo = incomeExpirationDate,
)
Expand All @@ -326,12 +340,15 @@ class OutdatedIncomeNotificationsIntegrationTest : FullApplicationTest(resetDbBe
@Test
fun `expiring income is notified if there is a handled income statement reaching after expiration`() {
val incomeExpirationDate = clock.today().plusWeeks(4)
val employee = DevEmployee()

db.transaction {
it.insert(employee)

it.insert(
DevIncome(
personId = fridgeHeadOfChildId,
modifiedBy = employeeEvakaUserId,
modifiedBy = AuthenticatedUser.SystemInternalUser.evakaUserId,
validFrom = incomeExpirationDate.minusMonths(1),
validTo = incomeExpirationDate,
)
Expand All @@ -343,7 +360,7 @@ class OutdatedIncomeNotificationsIntegrationTest : FullApplicationTest(resetDbBe
personId = fridgeHeadOfChildId,
data = createGrossIncome(incomeExpirationDate.plusDays(1)),
status = IncomeStatementStatus.HANDLED,
handlerId = employeeId,
handlerId = employee.id,
handledAt = clock.now(),
)
)
Expand All @@ -360,7 +377,7 @@ class OutdatedIncomeNotificationsIntegrationTest : FullApplicationTest(resetDbBe
it.insert(
DevIncome(
personId = fridgeHeadOfChildId,
modifiedBy = employeeEvakaUserId,
modifiedBy = AuthenticatedUser.SystemInternalUser.evakaUserId,
validFrom = incomeExpirationDate.minusMonths(1),
validTo = incomeExpirationDate,
)
Expand All @@ -386,7 +403,7 @@ class OutdatedIncomeNotificationsIntegrationTest : FullApplicationTest(resetDbBe
it.insert(
DevIncome(
personId = fridgeHeadOfChildId,
modifiedBy = employeeEvakaUserId,
modifiedBy = AuthenticatedUser.SystemInternalUser.evakaUserId,
validFrom = clock.today().minusMonths(1),
validTo = expirationDate,
)
Expand Down Expand Up @@ -423,7 +440,7 @@ class OutdatedIncomeNotificationsIntegrationTest : FullApplicationTest(resetDbBe
it.insert(
DevIncome(
personId = fridgeHeadOfChildId,
modifiedBy = employeeEvakaUserId,
modifiedBy = AuthenticatedUser.SystemInternalUser.evakaUserId,
validFrom = clock.today().minusMonths(1),
validTo = clock.today().plusDays(13),
)
Expand All @@ -445,7 +462,7 @@ class OutdatedIncomeNotificationsIntegrationTest : FullApplicationTest(resetDbBe
it.insert(
DevIncome(
personId = fridgeHeadOfChildId,
modifiedBy = employeeEvakaUserId,
modifiedBy = AuthenticatedUser.SystemInternalUser.evakaUserId,
validFrom = clock.today().minusMonths(1),
validTo = clock.today().plusWeeks(4),
)
Expand Down Expand Up @@ -486,7 +503,7 @@ class OutdatedIncomeNotificationsIntegrationTest : FullApplicationTest(resetDbBe
it.insert(
DevIncome(
personId = fridgeHeadOfChildId,
modifiedBy = employeeEvakaUserId,
modifiedBy = AuthenticatedUser.SystemInternalUser.evakaUserId,
validFrom = clock.today().minusMonths(1),
validTo = clock.today().plusDays(6),
)
Expand Down Expand Up @@ -537,7 +554,7 @@ class OutdatedIncomeNotificationsIntegrationTest : FullApplicationTest(resetDbBe
it.insert(
DevIncome(
personId = fridgeHeadOfChildId,
modifiedBy = employeeEvakaUserId,
modifiedBy = AuthenticatedUser.SystemInternalUser.evakaUserId,
validFrom = expirationDay.minusMonths(1),
validTo = expirationDay,
effect = IncomeEffect.INCOME,
Expand Down Expand Up @@ -666,7 +683,7 @@ class OutdatedIncomeNotificationsIntegrationTest : FullApplicationTest(resetDbBe
tx.insert(
DevIncome(
personId = fridgeHeadOfChildId,
modifiedBy = employeeEvakaUserId,
modifiedBy = AuthenticatedUser.SystemInternalUser.evakaUserId,
validFrom = clock.today().minusMonths(1),
validTo = clock.today().plusWeeks(4),
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ WITH latest_income AS (
FROM placement pl
JOIN service_need sn ON pl.id = sn.placement_id AND daterange(sn.start_date, sn.end_date, '[]') @> ${bind(dayAfterExpiration)}
JOIN service_need_option sno ON sn.option_id = sno.id AND sno.fee_coefficient > 0
JOIN daycare u ON u.id = pl.unit_id
-- head of child
JOIN fridge_child fc_head ON (
Expand All @@ -75,6 +76,7 @@ WITH latest_income AS (
JOIN latest_income i ON i.person_id = fc_head.head_of_child OR i.person_id = fp_spouse.person_id
WHERE between_start_and_end(${bind(checkForExpirationRange.asDateRange())}, i.valid_to)
AND (i.valid_to + INTERVAL '1 day')::date BETWEEN pl.start_date AND pl.end_date
AND u.invoiced_by_municipality
)
SELECT person_id, valid_to AS expiration_date
FROM expiring_income_with_billable_placement_day_after_expiration expiring_income
Expand Down