Query for tracking debt (and more)

I log the debt record in the journal page. Example:

#debt
person:: [[some person]]
amount:: 1000
direction:: to ; direction is "from" or "to"

Then I use the below query to track if anyone did not pay back yet or if I still borrow money from some one. I’m still struggling to format the number with comma separator. But I’m quite proud of this query. Took me 1 week to learn clojure, datomic and a lot of trials and errors for this query.

#+BEGIN_QUERY
{:title [:h2 "💴 Debt tracking"]
 :query [:find (pull ?p [:block/original-name :block/name :block/properties :block/created-at :block/updated-at]) ?amount ?sign
         :where
         (page-ref ?b "debt")
         (has-property ?b :amount)
         [?b :block/properties ?props]
         [(get ?props :person) ?person]
         [(get ?props :amount) ?amount]
         [(get ?props :direction) ?dir]
         [(get {"to" 1 "from" -1} ?dir) ?sign]
         [?p :block/original-name ?name]
         [(contains? ?person ?name)]]
 :result-transform (fn [result] 
                     (map (fn [[page amount]] (assoc-in page [:block/properties :total] amount))
                          (remove (fn[[page amount]] (zero? amount))
                                  (map (fn [group] (reduce (fn [acc n] (list (first n) (+ (second acc) (second n)))) group))
                                       (vals (group-by first (map (fn [[p a s]] (list p (* a s))) (partition 3 result))))))))}
#+END_QUERY

With a little tweak, this query can be used for other things that need accumulation over multiple records, like task effort tracking…

Nice! Looks really cool :smiley:

It took me one week to learn Logseq alone, nevermind its db design or language it is written in. (Datalog is fun though ;D) You really did all that in one week? You must be quite talented indeed. Keep it up, and thanks for sharing your work.

Keeping track of daily medication in a tablet log (or “Tablog” if you will) is done in a very similar way. It is very helpful for reminding me when I need to refill prescriptions, or to prevent accidental double dosing or missing a dose.