-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1564 from Opetushallitus/OK-553-application-unpai…
…d-state OK-553 hakemusmaksu payment states
- Loading branch information
Showing
6 changed files
with
334 additions
and
0 deletions.
There are no files selected for viewing
26 changes: 26 additions & 0 deletions
26
resources/db/migration/V20240611100500__create_kk_application_payment_tables.sql
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
CREATE TABLE kk_application_payment_states | ||
( | ||
id bigserial PRIMARY KEY, | ||
person_oid text NOT NULL, | ||
start_term text NOT NULL, | ||
start_year smallint NOT NULL, | ||
state text NOT NULL, | ||
created_time timestamp with time zone DEFAULT now(), | ||
modified_time timestamp with time zone DEFAULT now(), | ||
UNIQUE(person_oid, start_term, start_year) | ||
); | ||
|
||
COMMENT ON TABLE kk_application_payment_states IS 'Korkeakoulujen hakemusmaksujen tila aloituslukukausittain'; | ||
|
||
CREATE TABLE kk_application_payment_events | ||
( | ||
id bigserial PRIMARY KEY, | ||
kk_application_payment_state_id bigint REFERENCES kk_application_payment_states (id), | ||
new_state text, | ||
event_type text NOT NULL, | ||
virkailija_oid text REFERENCES virkailija(oid), | ||
message text, | ||
created_time timestamp with time zone DEFAULT now() | ||
); | ||
|
||
COMMENT ON TABLE kk_application_payment_events IS 'Korkeakoulujen hakemusmaksujen tilamuutoshistoria'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
-- name: yesql-get-kk-application-payment-states-for-person-oids | ||
SELECT | ||
id, | ||
person_oid, | ||
start_term, | ||
start_year, | ||
state, | ||
created_time, | ||
modified_time | ||
FROM kk_application_payment_states | ||
WHERE person_oid IN (:person_oids) AND start_term = :start_term AND start_year = :start_year; | ||
|
||
-- name: yesql-upsert-kk-application-payment-state<! | ||
INSERT INTO kk_application_payment_states (person_oid, start_term, start_year, state, created_time, modified_time) | ||
VALUES (:person_oid, :start_term, :start_year, :state, now(), now()) | ||
ON CONFLICT (person_oid, start_term, start_year) | ||
DO UPDATE SET state = :state, modified_time = now(); | ||
|
||
-- name: yesql-add-kk-application-payment-event<! | ||
INSERT INTO kk_application_payment_events (kk_application_payment_state_id, new_state, event_type, virkailija_oid, message) | ||
VALUES (:kk_application_payment_state_id, :new_state, :event_type, :virkailija_oid, :message); | ||
|
||
-- name: yesql-get-kk-application-payment-events | ||
SELECT | ||
id, | ||
kk_application_payment_state_id, | ||
new_state, | ||
event_type, | ||
virkailija_oid, | ||
message, | ||
created_time | ||
FROM kk_application_payment_events | ||
WHERE kk_application_payment_state_id IN (:kk_application_payment_state_ids); |
91 changes: 91 additions & 0 deletions
91
spec/ataru/kk_application_payment/kk_application_payment_spec.clj
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
(ns ataru.kk-application-payment.kk-application-payment-spec | ||
(:require [speclj.core :refer [describe tags it should-throw should= before-all]] | ||
[ataru.kk-application-payment.kk-application-payment :as payment] | ||
[clojure.java.jdbc :as jdbc] | ||
[ataru.db.db :as db])) | ||
|
||
(defn- delete-states-and-events! [] | ||
(jdbc/with-db-transaction [conn {:datasource (db/get-datasource :db)}] | ||
(jdbc/delete! conn :kk_application_payment_events []) | ||
(jdbc/delete! conn :kk_application_payment_states []))) | ||
|
||
(def test-term-spring "kausi_k") | ||
(def test-term-fall "kausi_s") | ||
(def test-term-error "kausi_a") | ||
(def test-year-ok 2025) | ||
(def test-year-error 2024) | ||
(def test-state-pending "payment-pending") | ||
(def test-state-not-required "payment-not-required") | ||
(def test-state-paid "payment-paid") | ||
(def test-event-updated "state-updated") | ||
|
||
(describe "application payment states" | ||
(tags :unit :kk-application-payment) | ||
|
||
(before-all | ||
(delete-states-and-events!)) | ||
|
||
(describe "payment state validation" | ||
(it "should not allow setting fee for spring 2025 (starts from fall 2025)" | ||
(should-throw (payment/set-application-fee-required | ||
"1.2.3.4.5.6" test-term-spring test-year-ok nil nil))) | ||
|
||
(it "should not allow setting fee for year earlier than 2025" | ||
(should-throw (payment/set-application-fee-required | ||
"1.2.3.4.5.6" test-term-spring test-year-error nil nil))) | ||
|
||
(it "should not allow setting fee for invalid term" | ||
(should-throw (payment/set-application-fee-required | ||
"1.2.3.4.5.6" test-term-error test-year-ok nil nil)))) | ||
|
||
(describe "payment state setting" | ||
(it "should set and get application fee required for a person with oid" | ||
(let [oid "1.2.3.4.5.6" | ||
state-id (payment/set-application-fee-required | ||
oid test-term-fall test-year-ok nil nil) | ||
states (payment/get-payment-states [oid] test-term-fall test-year-ok) | ||
events (payment/get-payment-events [state-id]) | ||
state (first states) | ||
event (first events)] | ||
(should= 1 (count states)) | ||
(should= 1 (count events)) | ||
(should= {:id state-id, :person_oid oid, :start_term test-term-fall, | ||
:start_year test-year-ok, :state test-state-pending} | ||
(dissoc state :created_time :modified_time)) | ||
(should= {:kk_application_payment_state_id state-id, :new_state test-state-pending, | ||
:event_type test-event-updated, :virkailija_oid nil, :message nil} | ||
(dissoc event :id :created_time)))) | ||
|
||
(it "should set and get application fee not required for a person with oid" | ||
(let [oid "1.2.3.4.5.7" | ||
state-id (payment/set-application-fee-not-required | ||
oid test-term-fall test-year-ok nil nil) | ||
states (payment/get-payment-states [oid] test-term-fall test-year-ok) | ||
events (payment/get-payment-events [state-id]) | ||
state (first states) | ||
event (first events)] | ||
(should= 1 (count states)) | ||
(should= 1 (count events)) | ||
(should= {:id state-id, :person_oid oid, :start_term test-term-fall, | ||
:start_year test-year-ok, :state test-state-not-required} | ||
(dissoc state :created_time :modified_time)) | ||
(should= {:kk_application_payment_state_id state-id, :new_state test-state-not-required, | ||
:event_type test-event-updated, :virkailija_oid nil, :message nil} | ||
(dissoc event :id :created_time)))) | ||
|
||
(it "should set and get application fee paid for a person with oid" | ||
(let [oid "1.2.3.4.5.8" | ||
state-id (payment/set-application-fee-paid | ||
oid test-term-fall test-year-ok nil nil) | ||
states (payment/get-payment-states [oid] test-term-fall test-year-ok) | ||
events (payment/get-payment-events [state-id]) | ||
state (first states) | ||
event (first events)] | ||
(should= 1 (count states)) | ||
(should= 1 (count events)) | ||
(should= {:id state-id, :person_oid oid, :start_term test-term-fall, | ||
:start_year test-year-ok, :state test-state-paid} | ||
(dissoc state :created_time :modified_time)) | ||
(should= {:kk_application_payment_state_id state-id, :new_state test-state-paid, | ||
:event_type test-event-updated, :virkailija_oid nil, :message nil} | ||
(dissoc event :id :created_time)))))) |
75 changes: 75 additions & 0 deletions
75
spec/ataru/kk_application_payment/kk_application_payment_store_spec.clj
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
(ns ataru.kk-application-payment.kk-application-payment-store-spec | ||
(:require [speclj.core :refer [describe tags it should-not-be-nil should= should-not before-all]] | ||
[ataru.kk-application-payment.kk-application-payment-store :as store] | ||
[ataru.db.db :as db] | ||
[clojure.java.jdbc :as jdbc])) | ||
|
||
(def test-person-oid "1.2.3.4.5.6") | ||
(def test-term-spring "kausi_k") | ||
(def test-term-fall "kausi_s") | ||
(def test-year 2025) | ||
(def test-year-2 2026) | ||
(def test-state-pending "payment-pending") | ||
(def test-state-paid "payment-paid") | ||
(def test-event-updated "state-updated") | ||
(def test-event-comment "comment") | ||
|
||
(defn- delete-states-and-events! [] | ||
(jdbc/with-db-transaction [conn {:datasource (db/get-datasource :db)}] | ||
(jdbc/delete! conn :kk_application_payment_events []) | ||
(jdbc/delete! conn :kk_application_payment_states []))) | ||
|
||
(describe "kk application payment states" | ||
(tags :unit :kk-application-payment) | ||
|
||
(before-all | ||
(delete-states-and-events!)) | ||
|
||
(it "should store payment states for person and terms" | ||
(let [spring-state (store/create-or-update-kk-application-payment-state! | ||
test-person-oid test-term-spring test-year test-state-pending) | ||
fall-state (store/create-or-update-kk-application-payment-state! | ||
test-person-oid test-term-fall test-year test-state-paid)] | ||
(should-not-be-nil (:id spring-state)) | ||
(should-not-be-nil (:id fall-state)) | ||
(should-not (= (:id spring-state) (:id fall-state))))) | ||
|
||
(it "should update a payment state for person" | ||
(let [new-state (store/create-or-update-kk-application-payment-state! | ||
test-person-oid test-term-spring test-year test-state-pending) | ||
updated-state (store/create-or-update-kk-application-payment-state! | ||
test-person-oid test-term-spring test-year test-state-paid)] | ||
(should= (:id new-state) (:id updated-state)))) | ||
|
||
(it "should get payment states for person" | ||
(let [spring-state-id (:id (store/create-or-update-kk-application-payment-state! | ||
test-person-oid test-term-spring test-year test-state-pending)) | ||
fall-state-id (:id (store/create-or-update-kk-application-payment-state! | ||
test-person-oid test-term-fall test-year test-state-paid)) | ||
spring-state (first (store/get-kk-application-payment-states [test-person-oid] test-term-spring test-year)) | ||
fall-state (first (store/get-kk-application-payment-states [test-person-oid] test-term-fall test-year)) | ||
expected-spring-state {:id spring-state-id :person_oid test-person-oid :start_term test-term-spring | ||
:start_year test-year :state test-state-pending} | ||
expected-fall-state {:id fall-state-id :person_oid test-person-oid :start_term test-term-fall | ||
:start_year test-year :state test-state-paid}] | ||
(should= expected-spring-state (dissoc spring-state :created_time :modified_time)) | ||
(should= expected-fall-state (dissoc fall-state :created_time :modified_time))))) | ||
|
||
(describe "kk application payment events" | ||
(tags :unit :kk-application-payment) | ||
|
||
(before-all | ||
(delete-states-and-events!)) | ||
|
||
(it "should store and retrieve payment events for payment state" | ||
(let [state-id (:id (store/create-or-update-kk-application-payment-state! | ||
test-person-oid test-term-spring test-year-2 test-state-pending)) | ||
event-1-id (store/create-kk-application-payment-event! | ||
state-id test-state-paid test-event-updated nil nil) | ||
event-2-id (store/create-kk-application-payment-event! | ||
state-id nil test-event-comment nil "Kommentti") | ||
events (store/get-kk-application-payment-events [state-id])] | ||
(should-not-be-nil event-1-id) | ||
(should-not-be-nil event-2-id) | ||
(should-not (= event-1-id event-2-id)) | ||
(should= 2 (count events))))) |
69 changes: 69 additions & 0 deletions
69
src/clj/ataru/kk_application_payment/kk_application_payment.clj
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
(ns ataru.kk-application-payment.kk-application-payment | ||
"Logic related to kk application processing payments, AKA hakemusmaksu. The basic spec is that | ||
non-exempt non-EU native applicants should be charged an application fee once per semester. | ||
NB! Semester is defined here by the start date of the actual first higher education semester, | ||
not the application date." | ||
(:require [ataru.kk-application-payment.kk-application-payment-store :as store] | ||
[taoensso.timbre :as log])) | ||
|
||
; TODO: application payments should be only charged for hakus starting on or after 1.1.2025 -> scoped to OK-556 | ||
|
||
(def application-payment-start-year | ||
"Application payments are charged from studies starting on 2025 or later." | ||
2025) | ||
|
||
(def valid-terms | ||
"Semesters / terms for kk application payments: one payment is required per starting term." | ||
#{:kausi_k :kausi_s}) | ||
|
||
(def valid-payment-states | ||
#{:payment-not-required | ||
:payment-pending | ||
:payment-paid}) | ||
|
||
(def valid-event-types | ||
#{:state-updated}) | ||
|
||
(defn start-term-valid? | ||
"Payments are only ever charged from Autumn 2025 onwards" | ||
[term year] | ||
(let [term-kw (keyword term)] | ||
(or | ||
(and (contains? valid-terms term-kw) (> year application-payment-start-year)) | ||
(and (= term-kw :kausi_s) (= year application-payment-start-year) )))) | ||
|
||
(defn- set-payment-state | ||
[person-oid term year new-state virkailija-oid message] | ||
(if (and (contains? valid-payment-states (keyword new-state)) | ||
(start-term-valid? term year)) | ||
(let [state-id (:id (store/create-or-update-kk-application-payment-state! | ||
person-oid term year new-state))] | ||
(store/create-kk-application-payment-event! state-id new-state "state-updated" virkailija-oid message) | ||
(log/info | ||
(str "Set payment state of person " person-oid " for term " term " " year " to " new-state)) | ||
state-id) | ||
(throw (ex-info "Parameter validation failed while setting payment state" | ||
{:person-oid person-oid :term term :year year :state new-state})))) | ||
|
||
(defn get-payment-states | ||
[person-oids term year] | ||
(store/get-kk-application-payment-states person-oids term year)) | ||
|
||
(defn get-payment-events | ||
[state-ids] | ||
(store/get-kk-application-payment-events state-ids)) | ||
|
||
(defn set-application-fee-required | ||
"Sets kk processing fee required for the target term." | ||
[person-oid term year virkailija-oid message] | ||
(set-payment-state person-oid term year "payment-pending" virkailija-oid message)) | ||
|
||
(defn set-application-fee-not-required | ||
"Sets kk processing fee required for the target term." | ||
[person-oid term year virkailija-oid message] | ||
(set-payment-state person-oid term year "payment-not-required" virkailija-oid message)) | ||
|
||
(defn set-application-fee-paid | ||
"Sets kk processing fee paid for the target term." | ||
[person-oid term year virkailija-oid message] | ||
(set-payment-state person-oid term year "payment-paid" virkailija-oid message)) |
40 changes: 40 additions & 0 deletions
40
src/clj/ataru/kk_application_payment/kk_application_payment_store.clj
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
(ns ataru.kk-application-payment.kk-application-payment-store | ||
(:require [ataru.db.db :as db] | ||
[yesql.core :refer [defqueries]])) | ||
|
||
(defqueries "sql/kk-application-payment-queries.sql") | ||
|
||
(declare yesql-get-kk-application-payment-states-for-person-oids) | ||
(declare yesql-upsert-kk-application-payment-state<!) | ||
(declare yesql-add-kk-application-payment-event<!) | ||
(declare yesql-get-kk-application-payment-events) | ||
|
||
(defn- exec-db | ||
[ds-key query params] | ||
(db/exec ds-key query params)) | ||
|
||
(defn create-or-update-kk-application-payment-state! | ||
[person-oid, start-term, start-year, state] | ||
(exec-db :db yesql-upsert-kk-application-payment-state<! {:person_oid person-oid | ||
:start_term start-term | ||
:start_year start-year | ||
:state state})) | ||
|
||
(defn get-kk-application-payment-states | ||
[person-oids start-term start-year] | ||
(exec-db :db yesql-get-kk-application-payment-states-for-person-oids {:person_oids person-oids | ||
:start_term start-term | ||
:start_year start-year})) | ||
|
||
(defn create-kk-application-payment-event! | ||
[payment-state-id, new-state, event-type, virkailija-oid, message] | ||
(exec-db :db yesql-add-kk-application-payment-event<! {:kk_application_payment_state_id payment-state-id | ||
:new_state new-state | ||
:event_type event-type | ||
:virkailija_oid virkailija-oid | ||
:message message})) | ||
|
||
(defn get-kk-application-payment-events | ||
[payment-state-ids] | ||
(exec-db :db yesql-get-kk-application-payment-events | ||
{:kk_application_payment_state_ids payment-state-ids})) |