Skip to content

Commit

Permalink
Merge pull request #6084 from espoon-voltti/fix-income-statement-draf…
Browse files Browse the repository at this point in the history
…t-visibility

Korjaus tuloilmoitusluonnosten näkyvyyteen virkailijoille
  • Loading branch information
Joosakur authored Dec 5, 2024
2 parents d778301 + ac438d0 commit 60faf2b
Show file tree
Hide file tree
Showing 5 changed files with 95 additions and 57 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import fi.espoo.evaka.invoicing.domain.IncomeEffect
import fi.espoo.evaka.pis.service.insertGuardian
import fi.espoo.evaka.placement.PlacementType
import fi.espoo.evaka.shared.AttachmentId
import fi.espoo.evaka.shared.EmployeeId
import fi.espoo.evaka.shared.IncomeStatementId
import fi.espoo.evaka.shared.PersonId
import fi.espoo.evaka.shared.PlacementId
Expand All @@ -34,6 +33,7 @@ import fi.espoo.evaka.shared.domain.DateRange
import fi.espoo.evaka.shared.domain.EvakaClock
import fi.espoo.evaka.shared.domain.HelsinkiDateTime
import fi.espoo.evaka.shared.domain.MockEvakaClock
import fi.espoo.evaka.shared.domain.NotFound
import fi.espoo.evaka.testAdult_1
import fi.espoo.evaka.testAdult_2
import fi.espoo.evaka.testAdult_3
Expand All @@ -51,6 +51,7 @@ import java.util.UUID
import kotlin.test.assertEquals
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.assertThrows
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.mock.web.MockMultipartFile

Expand All @@ -65,9 +66,8 @@ class IncomeStatementControllerIntegrationTest : FullApplicationTest(resetDbBefo
private val area2 = DevCareArea(name = "Area 2", shortName = "area2")
private val daycare2 = DevDaycare(areaId = area2.id)

private val employeeId = EmployeeId(UUID.randomUUID())
private val citizenId = testAdult_1.id
private val employee = AuthenticatedUser.Employee(employeeId, setOf(UserRole.FINANCE_ADMIN))
private val employee = DevEmployee(roles = setOf(UserRole.FINANCE_ADMIN))

private val today = LocalDate.of(2024, 8, 30)
private val now = HelsinkiDateTime.of(today, LocalTime.of(12, 0))
Expand All @@ -85,7 +85,7 @@ class IncomeStatementControllerIntegrationTest : FullApplicationTest(resetDbBefo
listOf(testChild_1, testChild_2, testChild_3, testChild_4, testChild_5).forEach {
tx.insert(it, DevPersonType.CHILD)
}
tx.insert(DevEmployee(id = employeeId, roles = setOf(UserRole.FINANCE_ADMIN)))
tx.insert(employee)
}
}

Expand All @@ -96,7 +96,7 @@ class IncomeStatementControllerIntegrationTest : FullApplicationTest(resetDbBefo

val incomeStatement =
DevIncomeStatement(
personId = testAdult_1.id,
personId = citizenId,
data = IncomeStatementBody.HighestFee(startDate, endDate),
status = IncomeStatementStatus.SENT,
createdAt = now.minusHours(10),
Expand All @@ -110,7 +110,7 @@ class IncomeStatementControllerIntegrationTest : FullApplicationTest(resetDbBefo
assertEquals(
IncomeStatement.HighestFee(
id = id,
personId = testAdult_1.id,
personId = citizenId,
firstName = testAdult_1.firstName,
lastName = testAdult_1.lastName,
startDate = startDate,
Expand All @@ -134,7 +134,7 @@ class IncomeStatementControllerIntegrationTest : FullApplicationTest(resetDbBefo
assertEquals(
IncomeStatement.HighestFee(
id = id,
personId = testAdult_1.id,
personId = citizenId,
firstName = testAdult_1.firstName,
lastName = testAdult_1.lastName,
startDate = startDate,
Expand Down Expand Up @@ -179,13 +179,42 @@ class IncomeStatementControllerIntegrationTest : FullApplicationTest(resetDbBefo
)
}

@Test
fun `cannot read draft statements`() {
val sentIncomeStatement =
DevIncomeStatement(
personId = citizenId,
data = IncomeStatementBody.HighestFee(today, today.plusDays(9)),
status = IncomeStatementStatus.SENT,
sentAt = now,
)
val draftIncomeStatement =
DevIncomeStatement(
personId = citizenId,
data = IncomeStatementBody.HighestFee(today.plusDays(10), today.plusDays(20)),
status = IncomeStatementStatus.DRAFT,
sentAt = null,
)
db.transaction {
it.insert(sentIncomeStatement)
it.insert(draftIncomeStatement)
}

assertEquals(
listOf(sentIncomeStatement.id),
getIncomeStatements(citizenId).data.map { it.id },
)
assertEquals(today, getIncomeStatement(sentIncomeStatement.id).startDate)
assertThrows<NotFound> { getIncomeStatement(draftIncomeStatement.id) }
}

@Test
fun `add an attachment`() {
val devIncomeStatement =
DevIncomeStatement(
personId = testAdult_1.id,
status = IncomeStatementStatus.DRAFT,
sentAt = null,
status = IncomeStatementStatus.SENT,
sentAt = now,
data =
IncomeStatementBody.Income(
startDate = today,
Expand Down Expand Up @@ -240,8 +269,8 @@ class IncomeStatementControllerIntegrationTest : FullApplicationTest(resetDbBefo
),
createdAt = incomeStatement.createdAt,
modifiedAt = incomeStatement.modifiedAt,
sentAt = null,
status = IncomeStatementStatus.DRAFT,
sentAt = now,
status = IncomeStatementStatus.SENT,
handledAt = null,
handlerNote = "",
),
Expand All @@ -265,7 +294,7 @@ class IncomeStatementControllerIntegrationTest : FullApplicationTest(resetDbBefo

return db.transaction { tx ->
tx.insert(incomeStatement)
tx.readIncomeStatementForPerson(personId, incomeStatement.id, true)!!
tx.readIncomeStatementForPerson(employee.user, personId, incomeStatement.id)!!
}
}

Expand All @@ -290,7 +319,7 @@ class IncomeStatementControllerIntegrationTest : FullApplicationTest(resetDbBefo

return db.transaction { tx ->
tx.insert(incomeStatement)
tx.readIncomeStatementForPerson(personId, incomeStatement.id, true)!!
tx.readIncomeStatementForPerson(employee.user, personId, incomeStatement.id)!!
}
}

Expand Down Expand Up @@ -1573,7 +1602,7 @@ class IncomeStatementControllerIntegrationTest : FullApplicationTest(resetDbBefo
private fun getIncomeStatement(id: IncomeStatementId): IncomeStatement {
return incomeStatementController.getIncomeStatement(
dbInstance(),
employee,
employee.user,
MockEvakaClock(now),
citizenId,
id,
Expand All @@ -1583,7 +1612,7 @@ class IncomeStatementControllerIntegrationTest : FullApplicationTest(resetDbBefo
private fun getIncomeStatements(personId: PersonId): PagedIncomeStatements {
return incomeStatementController.getIncomeStatements(
dbInstance(),
employee,
employee.user,
MockEvakaClock(now),
personId,
page = 1,
Expand All @@ -1596,7 +1625,7 @@ class IncomeStatementControllerIntegrationTest : FullApplicationTest(resetDbBefo
) {
incomeStatementController.setIncomeStatementHandled(
dbInstance(),
employee,
employee.user,
MockEvakaClock(now),
id,
body,
Expand All @@ -1619,7 +1648,7 @@ class IncomeStatementControllerIntegrationTest : FullApplicationTest(resetDbBefo
): PagedIncomeStatementsAwaitingHandler {
return incomeStatementController.getIncomeStatementsAwaitingHandler(
dbInstance(),
employee,
employee.user,
clock,
body,
)
Expand All @@ -1628,7 +1657,7 @@ class IncomeStatementControllerIntegrationTest : FullApplicationTest(resetDbBefo
private fun uploadAttachment(id: IncomeStatementId): AttachmentId {
return attachmentsController.uploadIncomeStatementAttachmentEmployee(
dbInstance(),
employee,
employee.user,
MockEvakaClock(now),
id,
MockMultipartFile("file", "evaka-logo.png", "image/png", pngFile.readBytes()),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ fun createValidatedIncomeStatement(
): IncomeStatementId {
if (!draft && !validateIncomeStatementBody(body)) throw BadRequest("Invalid income statement")

if (tx.incomeStatementExistsForStartDate(user.id, body.startDate)) {
if (tx.unhandledIncomeStatementExistsForStartDate(personId, body.startDate)) {
throw BadRequest("An income statement for this start date already exists")
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@ class IncomeStatementController(private val accessControl: AccessControl) {
personId,
)
it.readIncomeStatementsForPerson(
user = user,
personId = personId,
includeEmployeeContent = true,
page = page,
pageSize = 10,
)
Expand All @@ -71,18 +71,18 @@ class IncomeStatementController(private val accessControl: AccessControl) {
@PathVariable incomeStatementId: IncomeStatementId,
): IncomeStatement {
return db.connect { dbc ->
dbc.read {
dbc.read { tx ->
accessControl.requirePermissionFor(
it,
tx,
user,
clock,
Action.Person.READ_INCOME_STATEMENTS,
personId,
)
it.readIncomeStatementForPerson(
personId,
incomeStatementId,
includeEmployeeContent = true,
tx.readIncomeStatementForPerson(
user = user,
personId = personId,
incomeStatementId = incomeStatementId,
)
} ?: throw NotFound("No such income statement")
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@ class IncomeStatementControllerCitizen(private val accessControl: AccessControl)
user.id,
)
tx.readIncomeStatementsForPerson(
user.id,
includeEmployeeContent = false,
user = user,
personId = user.id,
page = page,
pageSize = 10,
)
Expand Down Expand Up @@ -84,8 +84,8 @@ class IncomeStatementControllerCitizen(private val accessControl: AccessControl)
childId,
)
tx.readIncomeStatementsForPerson(
childId,
includeEmployeeContent = false,
user = user,
personId = childId,
page = page,
pageSize = 10,
)
Expand Down Expand Up @@ -169,9 +169,9 @@ class IncomeStatementControllerCitizen(private val accessControl: AccessControl)
incomeStatementId,
)
tx.readIncomeStatementForPerson(
user.id,
incomeStatementId,
includeEmployeeContent = false,
user = user,
personId = user.id,
incomeStatementId = incomeStatementId,
) ?: throw NotFound("No such income statement")
}
}
Expand All @@ -196,9 +196,9 @@ class IncomeStatementControllerCitizen(private val accessControl: AccessControl)
incomeStatementId,
)
tx.readIncomeStatementForPerson(
PersonId(childId.raw),
incomeStatementId,
includeEmployeeContent = false,
user = user,
personId = childId,
incomeStatementId = incomeStatementId,
) ?: throw NotFound("No such child income statement")
}
}
Expand Down Expand Up @@ -289,7 +289,7 @@ class IncomeStatementControllerCitizen(private val accessControl: AccessControl)
Action.Citizen.IncomeStatement.UPDATE,
incomeStatementId,
)
verifyIncomeStatementModificationsAllowed(tx, user.id, incomeStatementId)
verifyIncomeStatementModificationsAllowed(tx, user, user.id, incomeStatementId)

tx.updateIncomeStatement(
user.evakaUserId,
Expand Down Expand Up @@ -333,7 +333,7 @@ class IncomeStatementControllerCitizen(private val accessControl: AccessControl)
Action.Citizen.IncomeStatement.UPDATE,
incomeStatementId,
)
verifyIncomeStatementModificationsAllowed(tx, childId, incomeStatementId)
verifyIncomeStatementModificationsAllowed(tx, user, childId, incomeStatementId)

tx.updateIncomeStatement(
user.evakaUserId,
Expand Down Expand Up @@ -371,7 +371,7 @@ class IncomeStatementControllerCitizen(private val accessControl: AccessControl)
Action.Citizen.IncomeStatement.DELETE,
id,
)
verifyIncomeStatementModificationsAllowed(tx, user.id, id)
verifyIncomeStatementModificationsAllowed(tx, user, user.id, id)
tx.removeIncomeStatement(id)
}
}
Expand All @@ -395,7 +395,7 @@ class IncomeStatementControllerCitizen(private val accessControl: AccessControl)
Action.Citizen.IncomeStatement.DELETE,
id,
)
verifyIncomeStatementModificationsAllowed(tx, childId, id)
verifyIncomeStatementModificationsAllowed(tx, user, childId, id)
tx.removeIncomeStatement(id)
}
}
Expand Down Expand Up @@ -431,11 +431,12 @@ class IncomeStatementControllerCitizen(private val accessControl: AccessControl)

private fun verifyIncomeStatementModificationsAllowed(
tx: Database.Transaction,
user: AuthenticatedUser.Citizen,
personId: PersonId,
id: IncomeStatementId,
) {
val incomeStatement =
tx.readIncomeStatementForPerson(personId, id, includeEmployeeContent = false)
tx.readIncomeStatementForPerson(user, personId, id)
?: throw NotFound("Income statement not found")
if (incomeStatement.status == IncomeStatementStatus.HANDLED) {
throw Forbidden("Handled income statement cannot be modified or removed")
Expand Down
Loading

0 comments on commit 60faf2b

Please sign in to comment.