@@ -11,6 +11,7 @@ import fi.espoo.evaka.shared.async.AsyncJobRunner
11
11
import fi.espoo.evaka.shared.db.Database
12
12
import fi.espoo.evaka.shared.domain.EvakaClock
13
13
import java.time.LocalDate
14
+ import java.time.YearMonth
14
15
import org.springframework.stereotype.Service
15
16
16
17
@Service
@@ -22,6 +23,59 @@ class InvoiceCorrectionMigrationService(asyncJobRunner: AsyncJobRunner<AsyncJob>
22
23
}
23
24
}
24
25
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
+
25
79
fun migrateInvoiceCorrection (
26
80
tx : Database .Transaction ,
27
81
clock : EvakaClock ,
0 commit comments