Files
integreat/src/clj/auto_ap/datomic/transactions.clj
2019-02-02 17:13:22 -08:00

128 lines
5.2 KiB
Clojure

(ns auto-ap.datomic.transactions
(:require [datomic.api :as d]
[auto-ap.datomic :refer [uri]]
[auto-ap.graphql.utils :refer [limited-clients]]
[clj-time.coerce :as c]))
(defn sort-fn [sort-by]
(cond
(= "client" sort-by)
#(-> % :transaction/client :client/name)
:else
(keyword "transaction" sort-by)))
;; TODO - unneeeded with merge-query
(defn add-where [query & wheres]
(reduce #(update-in %1 [:query :where] conj %2) query wheres))
;; TODO - unneeeded with merge-query
(defn add-wheres [query wheres]
(apply add-where query wheres))
;; TODO - unneeeded with merge-query
(defn add-arg [query name value where & rest]
(let [query (-> query
(update :args conj value)
(update-in [:query :in] conj name)
(update-in [:query :where] conj where))]
(reduce #(update-in %1 [:query :where] conj %2) query rest)))
(defn merge-query [query-part-1 query-part-2]
(-> query-part-1
(update-in [:query :find] into (get-in query-part-2 [:query :find]))
(update-in [:query :in] into (get-in query-part-2 [:query :in]))
(update-in [:query :where] into (get-in query-part-2 [:query :where]))
(update-in [:args] into (get-in query-part-2 [:args]))))
(defn add-sorter-field [q sort-map args]
(merge-query q
{:query {:find ['?sorter]
:where (sort-map
(:sort-by args)
(println "Warning, trying to sort by unsupported field" (:sort-by args)))}}))
(defn apply-sort [args sort-fn results ]
(cond->> results
sort-fn (sort-by sort-fn)
(= (:asc args) false) (reverse)))
(defn apply-sort-2 [args results ]
(let [comparator (if (= (:asc args) false)
(fn [x y] (compare y x))
(fn [x y] (compare x y)))]
(sort comparator results )))
(defn apply-pagination [args results]
{:ids (->> results
(drop (:start args 0))
(take (:count args 100))
(map last))
:count (count results)})
(defn raw-graphql-ids [db args]
(let [query (cond-> {:query {:find []
:in ['$ ]
:where []}
:args [db]}
(:sort-by args) (add-sorter-field {"client" ['[?e :transaction/client ?c]
'[?c :client/name ?sorter]]
"description-original" ['[?e :transaction/description-original ?sorter]]
"date" ['[?e :transaction/date ?sorter]]
"amount" ['[?e :transaction/amount ?sorter]]
"status" ['[?e :transaction/status ?sorter]]}
args)
(limited-clients (:id args))
(merge-query {:query {:in ['[?xx ...]]
:where ['[?e :transaction/client ?xx]]}
:args [(set (map :db/id (limited-clients (:id args))))]})
(:bank-account-id args)
(merge-query {:query {:in ['?bank-account-id]
:where ['[?e :transaction/bank-account ?bank-account-id]]}
:args [(:bank-account-id args)]})
(:client-id args)
(merge-query {:query {:in ['?client-id]
:where ['[?e :transaction/client ?client-id]]}
:args [(:client-id args)]})
(:client-code args)
(merge-query {:query {:in ['?client-code]
:where ['[?e :transaction/client ?client-id]
'[?client-id :client/code ?client-code]]}
:args [(:client-code args)]})
(:original-id args)
(merge-query {:query {:in ['?original-id]
:where ['[?e :transaction/client ?c]
'[?c :client/original-id ?original-id]]}
:args [(:original-id args)]})
true
(merge-query {:query {:find ['?e] :where ['[?e :transaction/id]]}}))]
(cond->> query
true (d/query)
(:sort-by args) (apply-sort-2 args)
true (apply-pagination args))))
(defn graphql-results [ids db args]
(->> (d/pull-many db '[* {:transaction/client [:client/name :db/id :client/code]
:transaction/bank-account [:bank-account/name :bank-account/code :bank-account/yodlee-account-id :db/id]}]
ids)
(map #(update % :transaction/date c/from-date))
(map #(update % :transaction/post-date c/from-date))
(apply-sort args (some-> (:sort-by args) sort-fn))))
(defn get-graphql [args]
(let [db (d/db (d/connect uri))
{ids-to-retrieve :ids matching-count :count} (raw-graphql-ids db args)]
[(->> (graphql-results ids-to-retrieve db args))
matching-count]))