Created
February 16, 2023 18:29
-
-
Save renanreismartins/e517def40182900e843b55b7a39ae3c1 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
(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)) |
;; 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
Does not matter for this solution but better to check:
When partitioning, what is the criteria of ordering of the partitions? For example, the collection (partition) of credits is the first returned. (Maybe based on order of the possible values on :type?)