(ns auto-ap.datomic.transactions (:require [datomic.api :as d] [auto-ap.datomic :refer [uri merge-query apply-sort-2 apply-sort apply-pagination add-sorter-field]] [auto-ap.graphql.utils :refer [limited-clients]] [clj-time.coerce :as c] [clj-time.coerce :as coerce])) (defn sort-fn [sort-by] (cond (= "client" sort-by) #(-> % :transaction/client :client/name) (= "account" sort-by) #(vector (-> % :transaction/account :account/name) (-> % :db/id)) :else (keyword "transaction" sort-by))) (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]] "account" ['[?e :transaction/date] '(or-join [?e ?sorter] (and [?e :transaction/account ?c] [?c :account/name ?sorter]) (and (not [?e :transaction/account]) [(ground "") ?sorter]))] "description-original" ['[?e :transaction/description-original ?sorter]] "date" ['[?e :transaction/date ?sorter]] "vendor" ['[?e :transaction/vendor ?v] '[?v :vendor/name ?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)]}) (:start (:date-range args)) (merge-query {:query {:in ['?start-date] :where ['[?e :transaction/date ?date] '[(>= ?date ?start-date)]]} :args [(coerce/to-date (:start (:date-range args)))]}) (:end (:date-range args)) (merge-query {:query {:in ['?end-date] :where ['[?e :transaction/date ?date] '[(<= ?date ?end-date)]]} :args [(coerce/to-date (:end (:date-range args)))]}) (:approval-status args) (merge-query {:query {:in ['?approval-status] :where ['[?e :transaction/approval-status ?approval-status]]} :args [(:approval-status 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 ['?base-date '?e] :where ['[?e :transaction/id] '[?e :transaction/date ?base-date]]}}))] (cond->> query true (d/query) true (apply-sort-2 args [:desc :asc]) true (apply-pagination args)))) (defn graphql-results [ids db args] (let [results (->> (d/pull-many db '[* {:transaction/client [:client/name :db/id :client/code] :transaction/approval-status [:db/ident :db/id] :transaction/bank-account [:bank-account/name :bank-account/code :bank-account/yodlee-account-id :db/id :bank-account/locations] :transaction/vendor [:db/id :vendor/name] :transaction/matched-rule [:db/id :transaction-rule/note] :transaction/accounts [:transaction-account/amount :db/id :transaction-account/location {:transaction-account/account [:db/id :account/name :account/numeric-code]}] :transaction/yodlee-merchant [:db/id :yodlee-merchant/yodlee-id :yodlee-merchant/name]}] ids) (map #(update % :transaction/date c/from-date)) (map #(update % :transaction/post-date c/from-date)) (map #(dissoc % :transaction/id)) (group-by :db/id))] (->> ids (map results) (map first)))) (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])) (defn get-by-id [id] (-> (d/pull (d/db (d/connect uri)) '[* {:transaction/client [:client/name :db/id :client/code :client/locations] :transaction/approval-status [:db/ident :db/id] :transaction/bank-account [:bank-account/name :bank-account/code :bank-account/yodlee-account-id :db/id :bank-account/locations] :transaction/vendor [:db/id :vendor/name] :transaction/matched-rule [:db/id :transaction-rule/note] :transaction/accounts [:transaction-account/amount :db/id :transaction-account/location { :transaction-account/account [:db/id :account/name :account/numeric-code]}] :transaction/yodlee-merchant [:db/id :yodlee-merchant/yodlee-id :yodlee-merchant/name]}] id) (update :transaction/date c/from-date) (update :transaction/post-date c/from-date) (dissoc :transaction/id)))