Skip to content

Instantly share code, notes, and snippets.

@renanreismartins
Created February 16, 2023 18:29
Show Gist options
  • Save renanreismartins/e517def40182900e843b55b7a39ae3c1 to your computer and use it in GitHub Desktop.
Save renanreismartins/e517def40182900e843b55b7a39ae3c1 to your computer and use it in GitHub Desktop.
(ns griffin.spec.journal-entry
(:require [clojure.spec.alpha :as s]))
(s/def ::id uuid?)
(s/def ::account-id uuid?)
(s/def ::type #{:credit :debit})
(s/def ::amount pos-int?)
(s/def ::line-item (s/keys :req-un [::account-id ::amount ::type]))
(s/def ::line-items (s/coll-of ::line-item :min-count 2))
(s/def ::journal-entry (s/keys :req-un [::id ::line-items]))
(def line-item-cred {
:account-id (java.util.UUID/fromString "f81d4fae-7dec-11d0-a765-00a0c91e6bf6")
:amount 100
:type :credit})
(def line-item-deb {
:account-id (java.util.UUID/fromString "f81d4fae-7dec-11d0-a765-00a0c91e6bf6")
:amount 100
:type :debit})
(def unbalanced-entry {
:id (java.util.UUID/fromString "4fe5d828-6444-11e8-8222-720007e40350")
:line-items [line-item-cred, line-item-cred, line-item-deb]})
(def balanced-entry {
:id (java.util.UUID/fromString "4fe5d828-6444-11e8-8222-720007e40350")
:line-items [line-item-cred, line-item-deb]})
;;
;; I'm assuming the following:
;; Each line-item we need to have a 'counter' line-item. Example: credit 100, debit 100.
;; Works only with :type is always credit or debit
;; I'm not correlating the account-id inside the items, but it would not be hard to do so
;; Could increase the test coverage for corner cases (empty collections, etc)
;; Could use a test framework :)
;; Probably this is not idiomatic, has been years since I wrote any Clojure
(defn total-amount [items] (reduce + (map :amount items)))
(defn credits-and-debits [entry] (partition-by :type (:line-items entry)))
(defn is-balanced [entry]
(let [[credits debits] (credits-and-debits entry)]
(and (= (count credits) (count debits))
(= 0 (- (total-amount credits) (total-amount debits))))))
(println "Balanced entry should return true: ")
(println (is-balanced balanced-entry))
(println)
(println "Unbalanced entry should return false: ")
(println (is-balanced unbalanced-entry))
@renanreismartins
Copy link
Author

;; Each line-item we need to have one or more 'counter' line-items. Example: credit 100, debit 100 or credit 100, debit 50, debit 50

Reviewing I found that for a ledger we must have the same number of counter transactions. So this is a bug

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment