(ns auto-ap.datomic.invoices (:require [datomic.api :as d] [auto-ap.datomic :refer [uri]] [clj-time.coerce :as c] [clojure.set :refer [rename-keys]] [clojure.string :as str])) (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))) (def default-read '(pull ?e [* {:invoice/client [:client/name :db/id :client/locations]} {:invoice/vendor [:vendor/name :db/id]} {:invoice/status [:db/ident]} {:invoice-payment/_invoice [* {:invoice-payment/payment [*]}]}])) (defn <-datomic [x] (->> x (map #(update % :invoice/date c/from-date)) (map #(update % :invoice/status :db/ident)) (map #(rename-keys % {:invoice-payment/_invoice :invoice/payments})))) (defn raw-graphql [args] (->> (d/query (cond-> {:query {:find [default-read] :in ['$] :where ['[?e :invoice/invoice-number]]} :args [(d/db (d/connect uri))]} (:client-id args) (add-arg '?client-id (:client-id args) '[?e :invoice/client ?client-id]) (:original-id args) (add-arg '?original-id (cond-> (:original-id args) (string? (:original-id args)) Long/parseLong ) '[?e :invoice/client ?c] '[?c :client/original-id ?original-id]) (:status args) (add-arg '?status (keyword "invoice-status" (:status args)) '[?e :invoice/status ?status]))) (map first) (<-datomic))) (defn sort-fn [args] (cond (= "client" (:sort-by args)) #(-> % :invoice/client :client/name .toLowerCase) (= "vendor" (:sort-by args)) #(-> % :invoice/vendor :vendor/name .toLowerCase) :else (keyword "invoice" (:sort-by args)))) (defn get-graphql [args] (let [results (raw-graphql args)] (cond->> results (:sort-by args) (sort-by (sort-fn args)) (= (:asc args) false) (reverse) true (drop (:start args 0)) true (take (:count args 20))))) (defn count-graphql [args] (->> (raw-graphql args) (count))) (defn get-by-id [id] (->> (d/query (-> {:query {:find [default-read] :in ['$] :where []} :args [(d/db (d/connect uri))]} (add-arg '?e id ['?e]))) (map first) (<-datomic) (first))) (defn update [update] @(d/transact (d/connect uri) [update]) (get-by-id (:db/id update) )) (defn get-multi [ids] (->> (d/query {:query {:find [[default-read '...]] :in ['$ ['?e '...]] :where [['?e]]} :args [(d/db (d/connect uri)) ids] } ) (<-datomic))) (defn find-conflicting [{:keys [:invoice/invoice-number :invoice/vendor :invoice/client :db/id]}] (->> (d/query (cond-> {:query {:find [default-read] :in ['$ '?invoice-number '?vendor '?client '?invoice-id] :where '[[?e :invoice/invoice-number ?invoice-number] [?e :invoice/vendor ?vendor] [?e :invoice/client ?client] [(not= ?e ?invoice-id)] ]} :args [(d/db (d/connect uri)) invoice-number vendor client (or id 0)]})) (map first) (<-datomic)))