Skip to content

Commit 5fd3768

Browse files
committed
migration as pure sql - testing
1 parent 869da0e commit 5fd3768

File tree

2 files changed

+64
-14
lines changed

2 files changed

+64
-14
lines changed

service/src/integrationTest/kotlin/fi/espoo/evaka/invoicing/service/InvoiceCorrectionMigrationServiceIntegrationTest.kt

+10-14
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,7 @@ import fi.espoo.evaka.shared.dev.DevPerson
1717
import fi.espoo.evaka.shared.dev.DevPersonType
1818
import fi.espoo.evaka.shared.dev.insert
1919
import fi.espoo.evaka.shared.domain.FiniteDateRange
20-
import fi.espoo.evaka.shared.domain.HelsinkiDateTime
21-
import fi.espoo.evaka.shared.domain.MockEvakaClock
2220
import java.time.LocalDate
23-
import java.time.LocalTime
2421
import java.time.YearMonth
2522
import kotlin.test.Test
2623
import kotlin.test.assertEquals
@@ -34,9 +31,6 @@ class InvoiceCorrectionMigrationServiceIntegrationTest : PureJdbiTest(resetDbBef
3431
private val daycare = DevDaycare(areaId = area.id)
3532
private val product = productProvider.mapToProduct(PlacementType.DAYCARE)
3633

37-
private val now = HelsinkiDateTime.of(LocalDate.of(2021, 6, 1), LocalTime.of(12, 0))
38-
private val clock = MockEvakaClock(now)
39-
4034
private fun insertBaseData() {
4135
db.transaction { tx ->
4236
tx.insert(adult, DevPersonType.ADULT)
@@ -91,7 +85,8 @@ class InvoiceCorrectionMigrationServiceIntegrationTest : PureJdbiTest(resetDbBef
9185
}
9286

9387
// when
94-
db.transaction { tx -> migrateInvoiceCorrection(tx, clock, correction.id) }
88+
val nextMonth = YearMonth.of(2021, 7)
89+
db.transaction { tx -> migrateInvoiceCorrections(tx, nextMonth) }
9590

9691
// then
9792
val corrections = db.read { it.getAllInvoiceCorrections() }
@@ -116,7 +111,7 @@ class InvoiceCorrectionMigrationServiceIntegrationTest : PureJdbiTest(resetDbBef
116111
}
117112

118113
@Test
119-
fun `migrateInvoiceCorrection splits correction and assigns target months`() {
114+
fun `migrateInvoiceCorrection splits correction and assigns target months and remaining correction retains amount if does not divide evenly`() {
120115
// given
121116
insertBaseData()
122117
val correctionReasonPeriod =
@@ -178,7 +173,7 @@ class InvoiceCorrectionMigrationServiceIntegrationTest : PureJdbiTest(resetDbBef
178173
val invoice2CorrectionRow =
179174
correction.toDevInvoiceRow(idx = 1).copy(amount = 1, unitPrice = -150)
180175

181-
// correction left = 10 * 200 - 3 * 200 - 1 * 150 = 1250
176+
// correction left = 10 * 200 - 3 * 200 - 1 * 150 = 1250 = 10 * 125
182177

183178
db.transaction { tx ->
184179
tx.insert(correction)
@@ -187,10 +182,11 @@ class InvoiceCorrectionMigrationServiceIntegrationTest : PureJdbiTest(resetDbBef
187182
}
188183

189184
// when
190-
db.transaction { tx -> migrateInvoiceCorrection(tx, clock, correction.id) }
185+
db.transaction { tx -> migrateInvoiceCorrections(tx, nextMonth) }
191186

192187
// then
193188
val corrections = db.read { it.getAllInvoiceCorrections() }
189+
println()
194190
assertEquals(
195191
listOf(
196192
correction.copy(
@@ -211,8 +207,8 @@ class InvoiceCorrectionMigrationServiceIntegrationTest : PureJdbiTest(resetDbBef
211207
id = corrections[2].id,
212208
targetMonth = nextMonth,
213209
appliedCompletely = false,
214-
amount = 1,
215-
unitPrice = -1250,
210+
amount = 10,
211+
unitPrice = -125,
216212
),
217213
),
218214
corrections,
@@ -230,7 +226,7 @@ class InvoiceCorrectionMigrationServiceIntegrationTest : PureJdbiTest(resetDbBef
230226
}
231227

232228
@Test
233-
fun `migrateInvoiceCorrection retains unit price when it divides evenly`() {
229+
fun `migrateInvoiceCorrections retains unit price when it divides evenly`() {
234230
// given
235231
insertBaseData()
236232
val correctionReasonPeriod =
@@ -279,7 +275,7 @@ class InvoiceCorrectionMigrationServiceIntegrationTest : PureJdbiTest(resetDbBef
279275
}
280276

281277
// when
282-
db.transaction { tx -> migrateInvoiceCorrection(tx, clock, correction.id) }
278+
db.transaction { tx -> migrateInvoiceCorrections(tx, nextMonth) }
283279

284280
// then
285281
val corrections = db.read { it.getAllInvoiceCorrections() }

service/src/main/kotlin/fi/espoo/evaka/invoicing/service/InvoiceCorrectionMigrationService.kt

+54
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import fi.espoo.evaka.shared.async.AsyncJobRunner
1111
import fi.espoo.evaka.shared.db.Database
1212
import fi.espoo.evaka.shared.domain.EvakaClock
1313
import java.time.LocalDate
14+
import java.time.YearMonth
1415
import org.springframework.stereotype.Service
1516

1617
@Service
@@ -22,6 +23,59 @@ class InvoiceCorrectionMigrationService(asyncJobRunner: AsyncJobRunner<AsyncJob>
2223
}
2324
}
2425

26+
fun migrateInvoiceCorrections(tx: Database.Transaction, nextMonth: YearMonth) {
27+
tx.execute {
28+
sql(
29+
"""
30+
WITH applied_corrections AS (
31+
SELECT ic.id AS original_correction_id, ext.uuid_generate_v1mc() AS new_correction_id, ir.id AS invoice_row_id, ic.created, ic.head_of_family_id, ic.child_id, ic.unit_id, ic.product, ic.period, ir.amount, ir.unit_price, ic.description, ic.note, i.period_start AS target_month
32+
FROM invoice_correction ic
33+
JOIN invoice_row ir ON ir.correction_id = ic.id
34+
JOIN invoice i ON ir.invoice_id = i.id
35+
), inserted_corrections AS (
36+
INSERT INTO invoice_correction (id, created, head_of_family_id, child_id, unit_id, product, period, amount, unit_price, description, note, applied_completely, target_month)
37+
SELECT ac.new_correction_id, ac.created, ac.head_of_family_id, ac.child_id, ac.unit_id, ac.product, ac.period, ac.amount, ac.unit_price, ac.description, ac.note, FALSE, ac.target_month
38+
FROM applied_corrections ac
39+
), updated_invoice_rows AS (
40+
UPDATE invoice_row ir
41+
SET correction_id = ac.new_correction_id
42+
FROM applied_corrections ac
43+
WHERE ir.id = ac.invoice_row_id
44+
RETURNING ir.*
45+
), remaining_corrections AS (
46+
SELECT ic.id, ic.amount * ic.unit_price - SUM(coalesce(ir.amount, 0) * coalesce(ir.unit_price, 0)) AS remaining_correction
47+
FROM invoice_correction ic
48+
LEFT JOIN applied_corrections ac ON ac.original_correction_id = ic.id
49+
LEFT JOIN updated_invoice_rows ir ON ir.correction_id = ac.new_correction_id
50+
WHERE ic.target_month IS NULL
51+
GROUP BY ic.id
52+
)
53+
UPDATE invoice_correction ic
54+
SET
55+
amount = CASE WHEN rc.remaining_correction % ic.unit_price = 0 THEN rc.remaining_correction / ic.unit_price ELSE ic.amount END,
56+
unit_price = CASE WHEN rc.remaining_correction % ic.unit_price = 0 THEN ic.unit_price ELSE rc.remaining_correction / ic.amount END,
57+
target_month = make_date(
58+
EXTRACT(YEAR FROM ${bind(nextMonth.atDay(1))})::int,
59+
EXTRACT(MONTH FROM ${bind(nextMonth.atDay(1))})::int,
60+
1
61+
),
62+
applied_completely = FALSE
63+
FROM remaining_corrections rc
64+
WHERE ic.id = rc.id AND rc.remaining_correction != 0;
65+
"""
66+
)
67+
}
68+
69+
tx.execute {
70+
sql(
71+
"""
72+
DELETE FROM invoice_correction
73+
WHERE target_month IS NULL;
74+
"""
75+
)
76+
}
77+
}
78+
2579
fun migrateInvoiceCorrection(
2680
tx: Database.Transaction,
2781
clock: EvakaClock,

0 commit comments

Comments
 (0)