(ns auto-ap.datomic.clients (:require [auto-ap.datomic :refer [add-sorter-fields apply-pagination apply-sort-3 conn merge-query pull-many query2]] [auto-ap.graphql.utils :refer [limited-clients]] [clj-time.coerce :as coerce] [clojure.string :as str] [com.brunobonacci.mulog :as mu] [datomic.api :as dc] [clj-http.client :as client] [auto-ap.solr :as solr])) (def full-read '[* {:client/square-integration-status [:integration-status/message :integration-status/last-attempt :integration-status/last-updated :db/id {:integration-status/state [:db/ident]}]} {:client/address [*]} {:client/square-locations [:square-location/square-id :square-location/name :square-location/client-location :db/id]} {:client/ezcater-locations [{:ezcater-location/caterer [:ezcater-caterer/name :db/id]} :ezcater-location/location :db/id]} {:client/bank-accounts [* {:bank-account/type [*] :bank-account/yodlee-account [:yodlee-account/name :yodlee-account/id :yodlee-account/number] :bank-account/plaid-account [:plaid-account/name :db/id :plaid-account/number :plaid-account/balance] :bank-account/intuit-bank-account [:intuit-bank-account/name :intuit-bank-account/external-id :db/id] :bank-account/integration-status [:integration-status/message :db/id :integration-status/last-attempt :integration-status/last-updated {:integration-status/state [:db/ident]}]} ]} {:yodlee-provider-account/_client [*]} {:plaid-item/_client [*]} {:client/emails [:db/id :email-contact/email :email-contact/description]}]) (defn cleanse [e] (-> e (assoc :client/yodlee-provider-accounts (get e :yodlee-provider-account/_client)) (assoc :client/plaid-items (get e :plaid-item/_client)) (update :client/locked-until #(some-> % coerce/to-date-time)) (update-in [:client/square-integration-status :integration-status/state] :db/ident) (update-in [:client/square-integration-status :integration-status/last-attempt] #(some-> % coerce/to-date-time)) (update-in [:client/square-integration-status :integration-status/last-updated] #(some-> % coerce/to-date-time)) (update :client/location-matches (fn [lms] (map #(assoc % :location-match/match (first (:location-match/matches %))) lms))) (update :client/bank-accounts (fn [bas] (map (fn [i ba] (-> ba (update :bank-account/type :db/ident ) (update-in [:bank-account/integration-status :integration-status/state] :db/ident) (update-in [:bank-account/integration-status :integration-status/last-attempt] #(some-> % coerce/to-date-time)) (update-in [:bank-account/integration-status :integration-status/last-updated] #(some-> % coerce/to-date-time)) (update :bank-account/start-date #(some-> % (coerce/to-date-time))) (update :bank-account/sort-order (fn [so] (or so i))))) (range) bas))))) (defn get-all [] (->> (dc/q '[:find (pull ?e r) :in $ r :where [?e :client/name]] (dc/db conn) full-read) (map first) (map cleanse))) (defn get-minimal [] (->> (dc/q '[:find (pull ?e [:client/name :client/code :client/locations :db/id {:client/bank-accounts [{:bank-account/type [:db/ident]} :bank-account/name :bank-account/sort-order :bank-account/bank-name :bank-account/visible :bank-account/current-balance :bank-account/locations :bank-account/code :db/id]}]) :where [?e :client/name]] (dc/db conn)) (map first) (map cleanse))) (defn get-by-id [id] (->> (dc/pull (dc/db conn ) full-read id) (cleanse))) (defn code->id [code] (->> (dc/q (-> {:find ['?e] :in ['$ '?code] :where [['?e :client/code '?code ]]} (dc/db conn) code)) (first) (first))) (defn best-match [identifier] (when (and identifier (not-empty identifier)) (some-> (solr/query solr/impl "clients" {"query" (format "_text_:\"%s\"" (str/upper-case (solr/escape identifier))) "fields" "id"}) first :id Long/parseLong))) (defn exact-match [identifier] (when (and identifier (not-empty identifier)) (some-> (solr/query solr/impl "clients" {"query" (format "exact:\"%s\"" (str/upper-case (solr/escape identifier))) "fields" "id"}) first :id Long/parseLong))) (defn rebuild-search-index [] (solr/index-documents-raw solr/impl "clients" (for [result (map first (dc/q '[:find (pull ?v [:client/name :client/matches :db/id :client/code]) :in $ :where [?v :client/code]] (dc/db conn))) :let [matches (conj (or (:client/matches result) []) (:client/name result))]] {"id" (:db/id result) "name" matches "code" (:client/code result) "exact" (map str/upper-case matches)}))) (defn raw-graphql-ids [db args] (let [query (cond-> {:query {:find [] :in ['$ ] :where []} :args [db]} (not (str/blank? (:code args))) (merge-query {:query {:in ['?client-code] :where ['[?e :client/code ?client-code]]} :args [(:code args)]}) (not (str/blank? (:name-like args))) (merge-query {:query {:in ['?name-like] :where ['[?e :client/name ?name] '[(clojure.string/includes? ?name ?name-like)]]} :args [(:name-like args)]}) (limited-clients (:id args)) (merge-query {:query {:in ['[?e ...]] :where []} :args [(set (map :db/id (limited-clients (:id args))))]}) (:sort args) (add-sorter-fields {"name" ['[?e :client/name ?sort-name]]} args) true (merge-query {:query {:find ['?sort-default '?e] :where ['[?e :client/name ?sort-default]]}}))] (->> (query2 query) (apply-sort-3 (update args :sort conj {:sort-key "default-2" :asc true})) (apply-pagination args)))) (defn graphql-results [ids db args] (let [results (->> (pull-many db full-read ids) (map cleanse))] results)) (defn get-graphql-page [args] (let [db (dc/db conn) {ids-to-retrieve :ids matching-count :count} (raw-graphql-ids db args)] [(->> (graphql-results ids-to-retrieve db args)) matching-count]))