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

OK-719 set tuition payment obligation together with kk application payment obligation #1669

Open
wants to merge 4 commits into
base: OK-770-kk-payment-attachment-deadline-logic
Choose a base branch
from
Open
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 @@ -10,7 +10,7 @@
[clojure.java.jdbc :as jdbc]
[clojure.string :as str]
[speclj.core :refer [it describe should-not-throw stub should-have-invoked should-not-have-invoked
tags with-stubs should= around before]]
should-be-nil tags with-stubs should= around before]]
[ataru.kk-application-payment.kk-application-payment :as payment]
[ataru.fixtures.application :as application-fixtures]
[ataru.fixtures.form :as form-fixtures]
Expand Down Expand Up @@ -85,6 +85,23 @@
(declare conn)
(declare spec)

(defn- get-tuition-payment-obligation-review [application-key hakukohde]
(jdbc/with-db-transaction [conn {:datasource (db/get-datasource :db)}]
(->> (jdbc/query
conn
["select * FROM application_hakukohde_reviews WHERE application_key = ? AND requirement = ? AND hakukohde = ?"
application-key "payment-obligation" hakukohde])
first)))

(defn- store-tuition-fee-not-required-review [application-key hakukohde]
(jdbc/with-db-transaction [conn {:datasource (db/get-datasource :db)}]
(jdbc/insert! conn "application_hakukohde_reviews"
{:application_key application-key
:requirement "payment-obligation"
:hakukohde hakukohde
:state "not-obligated"})))


(defn- clear! []
(jdbc/with-db-transaction [conn {:datasource (db/get-datasource :db)}]
(jdbc/delete! conn :applications [])
Expand Down Expand Up @@ -383,4 +400,106 @@
(should-have-invoked :start-job
{:with [:* :*
"ataru.kk-application-payment.kk-application-payment-email-job"
check-mail-fn]})))))
check-mail-fn]}))))

(it "should set tuition fee obligation for non fi/sv hakukohde when payment state changes to awaiting"
; Initial state: hakukohde in the application has only english as teaching language,
; and the application / person has no exemption, meaning the application should require both
; application fee AND tuition fee for the hakukohde.
(let [application-id (unit-test-db/init-db-fixture
vaeinoe marked this conversation as resolved.
Show resolved Hide resolved
form-fixtures/payment-exemption-test-form
application-fixtures/application-without-hakemusmaksu-exemption
nil)
_ (updater-job/update-kk-payment-status-for-person-handler
{:person_oid test-person-oid :term test-term :year test-year} runner)
application-key (:key (application-store/get-application application-id))
payment (first (payment/get-raw-payments [application-key]))
obligation (get-tuition-payment-obligation-review application-key "payment-info-test-kk-hakukohde")]
(should= (:awaiting payment/all-states) (:state payment))
(should= {:application_key application-key, :requirement "payment-obligation",
:state "obligated", :hakukohde "payment-info-test-kk-hakukohde"}
(select-keys obligation [:application_key :requirement :state :hakukohde]))))

(it "should set tuition fee obligation for non fi/sv hakukohde when payment state changes to ok-by-proxy"
; Initial state: hakukohde in both applications has only english as teaching language,
; and the application / person has no exemption, and we mark one of the applications paid manually.
; This means the other application should not require application payment BUT should still require
; tuition fee.
(let [application-ids (unit-test-db/init-db-fixture
form-fixtures/payment-exemption-test-form
[application-fixtures/application-without-hakemusmaksu-exemption
application-fixtures/application-without-hakemusmaksu-exemption])
[first-key second-key] (map #(:key (application-store/get-application %)) application-ids)
_ (payment-store/create-or-update-kk-application-payment!
{:application-key first-key
:state (:paid payment/all-states)
:reason nil
:due-date (time-format/unparse payment/default-time-format
(time/plus (time/today-at 12 0 0)
(time/days 3)))
:total-sum payment/kk-application-payment-amount
:maksut-secret test-maksut-secret
:required-at "now()"
:notification-sent-at nil
:approved-at "now()"})
_ (updater-job/update-kk-payment-status-for-person-handler
{:person_oid test-person-oid :term test-term :year test-year} runner)
payment (first (payment/get-raw-payments [second-key]))
obligation (get-tuition-payment-obligation-review second-key "payment-info-test-kk-hakukohde")]
(should= (:ok-by-proxy payment/all-states) (:state payment))
(should= {:application_key second-key, :requirement "payment-obligation",
:state "obligated", :hakukohde "payment-info-test-kk-hakukohde"}
(select-keys obligation [:application_key :requirement :state :hakukohde]))))

(it "should not set tuition fee obligation for non fi/sv hakukohde when payment state changes to not-required"
; Initial state: hakukohde in the application has only english as teaching language,
; but the application / person has an exemption, meaning the application should require neither
; application fee nor tuition fee for the hakukohde.
(let [application-id (unit-test-db/init-db-fixture
form-fixtures/payment-exemption-test-form
application-fixtures/application-with-hakemusmaksu-exemption
nil)
_ (updater-job/update-kk-payment-status-for-person-handler
{:person_oid test-person-oid :term test-term :year test-year} runner)
application-key (:key (application-store/get-application application-id))
payment (first (payment/get-raw-payments [application-key]))
obligation (get-tuition-payment-obligation-review application-key "payment-info-test-kk-hakukohde")]
(should= (:not-required payment/all-states) (:state payment))
(should-be-nil obligation)))

(it "should not set tuition fee obligation for fi/sv hakukohde"
; Initial state: hakukohde in the application has swedish and/or finnish in its teaching languages,
; so even the application / person has no exemption, the application should require only an
; application fee, but no tuition fee for the hakukohde.
(let [application-id (unit-test-db/init-db-fixture
form-fixtures/payment-exemption-test-form
(merge
application-fixtures/application-without-hakemusmaksu-exemption
{:hakukohde ["payment-info-test-kk-fisv-hakukohde"]})
nil)
_ (updater-job/update-kk-payment-status-for-person-handler
{:person_oid test-person-oid :term test-term :year test-year} runner)
application-key (:key (application-store/get-application application-id))
payment (first (payment/get-raw-payments [application-key]))
obligation (get-tuition-payment-obligation-review application-key "payment-info-test-kk-fisv-hakukohde")]
(should= (:awaiting payment/all-states) (:state payment))
(should-be-nil obligation)))

(it "should not override a non-automatic obligation"
; Initial state: hakukohde in the application has only english as teaching language,
; and application / person has no exemption, but there's a human review already for the tuition.
; Application fee should be required, but tuition fee state should not change automatically anymore.
(let [application-id (unit-test-db/init-db-fixture
form-fixtures/payment-exemption-test-form
application-fixtures/application-without-hakemusmaksu-exemption
nil)
application-key (:key (application-store/get-application application-id))
_ (store-tuition-fee-not-required-review application-key "payment-info-test-kk-hakukohde")
_ (updater-job/update-kk-payment-status-for-person-handler
{:person_oid test-person-oid :term test-term :year test-year} runner)
payment (first (payment/get-raw-payments [application-key]))
obligation (get-tuition-payment-obligation-review application-key "payment-info-test-kk-hakukohde")]
(should= (:awaiting payment/all-states) (:state payment))
(should= {:application_key application-key, :requirement "payment-obligation",
:state "not-obligated", :hakukohde "payment-info-test-kk-hakukohde"}
(select-keys obligation [:application_key :requirement :state :hakukohde])))))
13 changes: 13 additions & 0 deletions src/clj/ataru/applications/application_store.clj
Original file line number Diff line number Diff line change
Expand Up @@ -842,6 +842,8 @@
(queries/yesql-add-application-event<! event connection))))))

(defn save-payment-obligation-automatically-changed
"Only used by automatic tuition fee obligation logic. Sets new obligation state if previous one was not set by
virkailija and the state transition is allowed. If successful, adds an event marking the obligation was set automatically."
[application-key hakukohde-oid hakukohde-review-requirement hakukohde-review-state]
(jdbc/with-db-transaction [conn {:datasource (db/get-datasource :db)}]
(let [connection {:connection conn}
Expand All @@ -856,11 +858,22 @@
:event_type
(= "payment-obligation-automatically-changed"))
existing-requirement-review (first (queries/yesql-get-existing-requirement-review review-to-store connection))]
; Main idea:
; - When the state is still unreviewed, it can be always automatically changed.
; - When virkailija has made the latest modification to tuition fee obligation (not automatically-changed?)
; we should never override that state automatically anymore.
; - Once the state is automatically set as obligated, don't modify further without virkailija input.
(when (or (and (= "not-obligated" (:state review-to-store))
(= "unreviewed" (:state existing-requirement-review "unreviewed")))
(and (= "unreviewed" (:state review-to-store))
(= "not-obligated" (:state existing-requirement-review))
vaeinoe marked this conversation as resolved.
Show resolved Hide resolved
automatically-changed?)
(and (= "obligated" (:state review-to-store))
(= "unreviewed" (:state existing-requirement-review "unreviewed")))
(and (= "obligated" (:state review-to-store))
(= "not-obligated" (:state existing-requirement-review))
automatically-changed?))
; Whenever we set the obligation automatically, also add an event for auditing and possible further state changes.
(queries/yesql-upsert-application-hakukohde-review! review-to-store connection)
(let [event {:application_key application-key
:event_type "payment-obligation-automatically-changed"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,8 @@
(time/plus (time/today-at 12 0 0)
(time/days kk-application-payment-due-days))))

; This could be done automatically on every DB select, but needed so rarely that let's just convert on demand.
(defn parse-due-date
"Convert due date retrieved from db to local date, interpreting it in correct time zone"
"Convert due date timestamp retrieved from db to local date"
[due-date]
(time/local-date (time/year due-date) (time/month due-date) (time/day due-date)))

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
[clj-time.core :as time]
[clj-time.format :as f]
[clojure.java.jdbc :as jdbc]
[clojure.string :as str]
[taoensso.timbre :as log]
[ataru.config.core :refer [config]]
[ataru.kk-application-payment.kk-application-payment-email-job :as email-job]
Expand Down Expand Up @@ -119,6 +120,36 @@
(payment/get-valid-payment-info-for-application-id tarjonta-service application-id)
(payment/get-valid-payment-info-for-application-key tarjonta-service application-key))))

(defn- needs-tuition-fee?
[hakukohde]
(let [codes (->> (:opetuskieli-koodi-urit hakukohde)
(map #(first (str/split % #"#")))
set)]
(and (seq codes)
(not (contains? codes "oppilaitoksenopetuskieli_1")) ; fi
(not (contains? codes "oppilaitoksenopetuskieli_2")) ; sv
(not (contains? codes "oppilaitoksenopetuskieli_3"))))) ; fi/sv

(defn- mark-tuition-fee-obligated
"Marks tuition fee (lukuvuosimaksu) obligation for application key for every hakukohde that does not organize
studies in Finnish and/or Swedish."
[{:keys [tarjonta-service]} application-key]
(let [application (application-store/get-latest-application-by-key application-key)
hakukohde-oids (:hakukohde application)
hakukohteet (tarjonta/get-hakukohteet
tarjonta-service
(remove nil? hakukohde-oids))
tuition-hakukohde-oids (remove nil?
(map #(when (needs-tuition-fee? %) (:oid %)) hakukohteet))]
(doseq [hakukohde-oid tuition-hakukohde-oids]
(log/info "Marking tuition payment obligation due to kk application fee eligibility for application key"
application-key "and hakukohde oid" hakukohde-oid)
(application-store/save-payment-obligation-automatically-changed
application-key
hakukohde-oid
"payment-obligation"
vaeinoe marked this conversation as resolved.
Show resolved Hide resolved
"obligated"))))

(defn- invalidate-maksut-payments-if-needed
"Whenever a payment for a term is made, other payment invoices for the person and term
should be invalidated to avoid accidental double payments."
Expand All @@ -132,8 +163,9 @@

(defn update-kk-payment-status-for-person-handler
"Updates payment requirement status for a single (person oid, term, year) either directly or
via an application id/key. Creates payments and sends e-mails when necessary. Marking status as paid/overdue
is done separately via kk-application-payment-maksut-poller-job, never here."
via an application id/key. Creates payments and sends e-mails when necessary. Also marks tuition fee obligation
if necessary. Marking status as paid/overdue is done separately via kk-application-payment-maksut-poller-job,
never here."
[{:keys [person_oid term year application_id application_key]}
{:keys [ohjausparametrit-service person-service tarjonta-service
koodisto-cache get-haut-cache maksut-service] :as job-runner}]
Expand All @@ -151,7 +183,13 @@
(let [new-state (:state payment)]
(cond
(= (:awaiting payment/all-states) new-state)
(create-payment-and-send-email job-runner maksut-service payment))))
(do
(create-payment-and-send-email job-runner maksut-service payment)
; If application payment is required, tuition fee will be always required as well.
(mark-tuition-fee-obligated job-runner (:application-key payment)))

(= (:ok-by-proxy payment/all-states) new-state)
(mark-tuition-fee-obligated job-runner (:application-key payment)))))

(doseq [application-payment existing-payments]
(let [{:keys [application payment]} application-payment]
Expand Down
9 changes: 8 additions & 1 deletion src/clj/ataru/tarjonta_service/mock_tarjonta_service.clj
Original file line number Diff line number Diff line change
Expand Up @@ -550,7 +550,14 @@
:payment-info-test-kk-hakukohde (merge
base-kouta-hakukohde
{:oid "payment-info-test-kk-hakukohde"
:johtaaTutkintoon true})
:johtaaTutkintoon true
:opetuskieliKoodiUrit ["oppilaitoksenopetuskieli_4#2"]})
:payment-info-test-kk-fisv-hakukohde (merge
base-kouta-hakukohde
{:oid "payment-info-test-kk-fisv-hakukohde"
:johtaaTutkintoon true
:opetuskieliKoodiUrit ["oppilaitoksenopetuskieli_2#2"
"oppilaitoksenopetuskieli_4#2"]})
:payment-info-test-kk-no-tutkinto-hakukohde (merge
base-kouta-hakukohde
{:oid "payment-info-test-kk-no-tutkinto-hakukohde"
Expand Down
Loading