(ns auto-ap.datomic.sales-orders (:require [auto-ap.datomic :refer [add-sorter-fields apply-pagination apply-sort-3 merge-query uri]] [auto-ap.graphql.utils :refer [limited-clients]] [clj-time.coerce :as c] [datomic.api :as d] [clojure.tools.logging :as log] [clojure.set :as set])) (defn <-datomic [result] (-> result (update :sales-order/date c/from-date) (update :sales-order/charges (fn [cs] (map (fn [c] (-> c (update :charge/processor :db/ident) (set/rename-keys {:expected-deposit/_charges :expected-deposit}) (update :expected-deposit first))) cs))))) (def default-read '[* {:sales-order/client [:client/name :db/id :client/code] :sales-order/charges [* {:charge/processor [:db/ident]} {:expected-deposit/_charges [:db/id]}]}]) (defn raw-graphql-ids [db args] (let [query (cond-> {:query {:find [] :in ['$] :where []} :args [db]} (:sort args) (add-sorter-fields {"client" ['[?e :sales-order/client ?c] '[?c :client/name ?sort-client]] "location" ['[?e :sales-order/location ?sort-location]] "source" ['[?e :sales-order/source ?sort-source]] "date" ['[?e :sales-order/date ?sort-date]] "total" ['[?e :sales-order/total ?sort-total]] "tax" ['[?e :sales-order/tax ?sort-tax]] "tip" ['[?e :sales-order/tip ?sort-tip]]} args) (:start (:date-range args)) (merge-query {:query {:in '[?start-date] :where ['[?e :sales-order/date ?date] '[(>= ?date ?start-date)]]} :args [(c/to-date (:start (:date-range args)))]}) (:end (:date-range args)) (merge-query {:query {:in '[?end-date] :where ['[?e :sales-order/date ?date] '[(<= ?date ?end-date)]]} :args [(c/to-date (:end (:date-range args)))]}) (limited-clients (:id args)) (merge-query {:query {:in ['[?xx ...]] :where ['[?e :sales-order/client ?xx]]} :args [(set (map :db/id (limited-clients (:id args))))]}) (:client-id args) (merge-query {:query {:in ['?client-id] :where ['[?e :sales-order/client ?client-id]]} :args [(:client-id args)]}) (:client-code args) (merge-query {:query {:in ['?client-code] :where ['[?e :sales-order/client ?client-id] '[?client-id :client/code ?client-code]]} :args [(:client-code args)]}) (:category args) (merge-query {:query {:in ['?category] :where ['[?e :sales-order/line-items ?li] '[?li :order-line-item/category ?category]]} :args [(:category args)]}) (:processor args) (merge-query {:query {:in ['?processor] :where ['[?e :sales-order/charges ?chg] '[?chg :charge/processor ?processor]]} :args [(keyword "ccp-processor" (name (:processor args)))]}) (:type-name args) (merge-query {:query {:in ['?type-name] :where ['[?e :sales-order/charges ?chg] '[?chg :charge/type-name ?type-name]]} :args [(:type-name args)]}) (:total-gte args) (merge-query {:query {:in ['?total-gte] :where ['[?e :sales-order/total ?a] '[(>= ?a ?total-gte)]]} :args [(:total-gte args)]}) (:total-lte args) (merge-query {:query {:in ['?total-lte] :where ['[?e :sales-order/total ?a] '[(<= ?a ?total-lte)]]} :args [(:total-lte args)]}) (:total args) (merge-query {:query {:in ['?total] :where ['[?e :sales-order/total ?sales-order-total] '[(auto-ap.utils/dollars= ?sales-order-total ?total)]]} :args [(:total args)]}) true (merge-query {:query {:find ['?sort-default '?e] :where ['[?e :sales-order/date ?sort-default]]}}))] (log/info "Sales query" query) (cond->> query true (d/query) true (apply-sort-3 (assoc args :default-asc? false)) true (apply-pagination args)))) (defn graphql-results [ids db _] (let [results (->> (d/pull-many db default-read ids) (group-by :db/id)) payments (->> ids (map results) (map first) (mapv <-datomic))] payments)) (defn summarize-orders [ids] (let [[total tax] (->> (d/query {:query {:find ['(sum ?t) '(sum ?tax)] :with ['?id] :in ['$ '[?id ...]] :where ['[?id :sales-order/total ?t] '[?id :sales-order/tax ?tax]]} :args [(d/db (d/connect uri)) ids]}) first)] {:total total :tax tax})) (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 (summarize-orders ids-to-retrieve)]))