Skip to content
/ bits Public

Commit 9b7b887

Browse files
committed
WIP Schema
1 parent 4ed66aa commit 9b7b887

3 files changed

Lines changed: 599 additions & 6 deletions

File tree

src/bits/entity.clj

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
(ns bits.entity
2+
(:require
3+
[clojure.spec.alpha :as s]))
4+
5+
;;; ----------------------------------------------------------------------------
6+
;;; Money
7+
8+
(s/def :money/amount pos-int?)
9+
(s/def :money/currency keyword?)
10+
11+
(s/def :posting/account uuid?)
12+
(s/def :posting/amount pos-int?)
13+
(s/def :posting/direction #{:posting.direction/credit :posting.direction/debit})

src/bits/ledger.clj

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
(ns bits.ledger
2+
(:require
3+
[clojure.spec.alpha :as s]
4+
[datomic.api :as d]
5+
[java-time.api :as time]))
6+
7+
;;; ----------------------------------------------------------------------------
8+
;;; Queries
9+
10+
(def account-by-code-query
11+
'[:find (pull ?a [*]) .
12+
:in $ ?code
13+
:where
14+
[?a :ledger-account/code ?code]])
15+
16+
(def account-debits-query
17+
'[:find (sum ?amount) .
18+
:in $ ?account-eid
19+
:where
20+
[?posting :posting/account ?account-eid]
21+
[?posting :posting/direction :posting.direction/debit]
22+
[?posting :posting/amount ?amount]
23+
[?je :journal-entry/postings ?posting]
24+
[?je :journal-entry/status :journal-entry.status/posted]])
25+
26+
(def account-credits-query
27+
'[:find (sum ?amount) .
28+
:in $ ?account-eid
29+
:where
30+
[?posting :posting/account ?account-eid]
31+
[?posting :posting/direction :posting.direction/credit]
32+
[?posting :posting/amount ?amount]
33+
[?je :journal-entry/postings ?posting]
34+
[?je :journal-entry/status :journal-entry.status/posted]])
35+
36+
;;; ----------------------------------------------------------------------------
37+
;;; Balance calculation
38+
39+
(def debit-normal-types
40+
#{:ledger-account.type/asset :ledger-account.type/expense})
41+
42+
(defn calculate-balance
43+
[account-type debits credits]
44+
(if (debit-normal-types account-type)
45+
(- (or debits 0) (or credits 0))
46+
(- (or credits 0) (or debits 0))))
47+
48+
;;; ----------------------------------------------------------------------------
49+
;;; Validation (convenience — early feedback, not source of truth)
50+
51+
(defn validate-balanced
52+
[postings]
53+
(let [sum-by (fn [dir]
54+
(->> postings
55+
(filter #(= dir (:posting/direction %)))
56+
(map :posting/amount)
57+
(reduce + 0)))
58+
debits (sum-by :posting.direction/debit)
59+
credits (sum-by :posting.direction/credit)]
60+
(when (not= debits credits)
61+
{:error :unbalanced
62+
:debits debits
63+
:credits credits})))
64+
65+
;;; ----------------------------------------------------------------------------
66+
;;; Transaction data
67+
68+
(defn ledger-account-tx
69+
[{:keys [code name type currency description]
70+
:or {description nil}}]
71+
(cond-> {:ledger-account/id (d/squuid)
72+
:ledger-account/code code
73+
:ledger-account/name name
74+
:ledger-account/type type
75+
:ledger-account/currency currency
76+
:ledger-account/active? true
77+
:ledger-account/created-at (time/java-date)}
78+
description (assoc :ledger-account/description description)))
79+
80+
(defn default-accounts-txes
81+
[currency]
82+
[(ledger-account-tx {:code "asset:incoming-payments"
83+
:name "Incoming Payments"
84+
:type :ledger-account.type/asset
85+
:currency currency})
86+
87+
(ledger-account-tx {:code "asset:platform-holdings"
88+
:name "Platform Holdings"
89+
:type :ledger-account.type/asset
90+
:currency currency})
91+
92+
(ledger-account-tx {:code "liability:creator-balance"
93+
:name "Creator Balance"
94+
:type :ledger-account.type/liability
95+
:currency currency})
96+
97+
(ledger-account-tx {:code "liability:buyer-refunds-due"
98+
:name "Buyer Refunds Due"
99+
:type :ledger-account.type/liability
100+
:currency currency})
101+
102+
(ledger-account-tx {:code "revenue:platform-fees"
103+
:name "Platform Fees"
104+
:type :ledger-account.type/revenue
105+
:currency currency})
106+
107+
(ledger-account-tx {:code "expense:processor-fees"
108+
:name "Processor Fees"
109+
:type :ledger-account.type/expense
110+
:currency currency})
111+
112+
(ledger-account-tx {:code "expense:refunds-issued"
113+
:name "Refunds Issued"
114+
:type :ledger-account.type/expense
115+
:currency currency})])

0 commit comments

Comments
 (0)