User can set up sales queries on their own now.
This commit is contained in:
@@ -12,6 +12,7 @@
|
||||
[auto-ap.datomic.migrate.invoice-converter
|
||||
:refer [add-import-status-existing-invoices]]
|
||||
[auto-ap.datomic.migrate.ledger :as ledger]
|
||||
[auto-ap.datomic.migrate.queries :as queries]
|
||||
[auto-ap.datomic.migrate.plaid :as plaid]
|
||||
[auto-ap.datomic.migrate.sales :as sales]
|
||||
[auto-ap.datomic.migrate.vendors :as vendors]
|
||||
@@ -501,7 +502,8 @@
|
||||
reports/norms-map
|
||||
plaid/norms-map
|
||||
audit/norms-map
|
||||
vendors/norms-map)]
|
||||
vendors/norms-map
|
||||
queries/norms-map)]
|
||||
(println "Conforming database...")
|
||||
(c/ensure-conforms conn norms-map)
|
||||
#_(when (not (seq args))
|
||||
|
||||
@@ -4,16 +4,17 @@
|
||||
[auto-ap.graphql.utils :refer [->graphql assert-admin can-see-client? is-admin?]]
|
||||
[auto-ap.utils :refer [by]]
|
||||
[auto-ap.yodlee.core :refer [in-memory-cache]]
|
||||
[auto-ap.routes.queries :as q]
|
||||
[auto-ap.square.core :as square]
|
||||
[com.walmartlabs.lacinia.util :refer [attach-resolvers]]
|
||||
[clj-time.coerce :as coerce]
|
||||
[config.core :refer [env]]
|
||||
[clojure.string :as str]
|
||||
[unilog.context :as lc]
|
||||
[clojure.tools.logging :as log]
|
||||
[datomic.api :as d]
|
||||
[clojure.java.io :as io]
|
||||
[amazonica.aws.s3 :as s3]
|
||||
#_{:clj-kondo/ignore [:unused-namespace]}
|
||||
[yang.scheduler :as scheduler]
|
||||
[mount.core :as mount])
|
||||
(:import [org.apache.commons.codec.binary Base64]
|
||||
@@ -51,7 +52,7 @@
|
||||
[?ba :bank-account/plaid-account ?src]
|
||||
[?ba :bank-account/yodlee-account-id ?src])]
|
||||
new-db [:client/code client-code])
|
||||
(filter (fn [[src cnt]]
|
||||
(filter (fn [[_ cnt]]
|
||||
(> cnt 1)))))
|
||||
(throw (ex-info "Cannot reuse yodlee/plaid/intuit account" {:validation-error (str "Cannot reuse yodlee/plaid/intuit account")})))))
|
||||
|
||||
@@ -183,11 +184,11 @@
|
||||
[(get-else $ ?e :journal-entry-line/credit 0.0) ?credit]]}
|
||||
:args [(d/db conn) bank-account-id]})
|
||||
debits (->> all-transactions
|
||||
(map (fn [[e debit credit]]
|
||||
(map (fn [[_ debit _]]
|
||||
debit))
|
||||
(reduce + 0.0))
|
||||
credits (->> all-transactions
|
||||
(map (fn [[e debit credit]]
|
||||
(map (fn [[_ _ credit]]
|
||||
credit))
|
||||
(reduce + 0.0))
|
||||
current-balance (if (= :bank-account-type/check (:bank-account/type (d/entity (d/db conn) bank-account-id)))
|
||||
@@ -255,7 +256,7 @@
|
||||
:start (scheduler/every (* 17 60 1000) refresh-current-balance)
|
||||
:stop (scheduler/stop current-balance-worker))
|
||||
|
||||
(defn get-client [context args value]
|
||||
(defn get-client [context _ _]
|
||||
(->graphql
|
||||
(->> (d-clients/get-all)
|
||||
(filter #(can-see-client? (:id context) %))
|
||||
@@ -276,6 +277,140 @@
|
||||
|
||||
|
||||
|
||||
(def sales-summary-query
|
||||
"[:find ?d4 (sum ?total) (sum ?tax) (sum ?tip) (sum ?service-charge) (sum ?discount) (sum ?returns)
|
||||
:with ?s
|
||||
:in $
|
||||
:where
|
||||
[?s :sales-order/client [:client/code \"%s\"]]
|
||||
[?s :sales-order/date ?d]
|
||||
[?s :sales-order/total ?total]
|
||||
[?s :sales-order/tax ?tax]
|
||||
[?s :sales-order/tip ?tip]
|
||||
[?s :sales-order/service-charge ?service-charge]
|
||||
[?s :sales-order/returns ?returns]
|
||||
[?s :sales-order/discount ?discount]
|
||||
[(clj-time.coerce/to-date-time ?d) ?d2]
|
||||
[(auto-ap.time/localize ?d2) ?d3]
|
||||
[(auto-ap.time/unparse-local ?d3 auto-ap.time/normal-date) ?d4]
|
||||
]")
|
||||
|
||||
(def sales-category-query
|
||||
"[:find ?d4 ?n ?n2 (sum ?total) (sum ?tax) (sum ?discount)
|
||||
:with ?s ?li
|
||||
:in $
|
||||
:where
|
||||
[?s :sales-order/client [:client/code \"%s\"]]
|
||||
[?s :sales-order/date ?d]
|
||||
[?s :sales-order/line-items ?li]
|
||||
[?li :order-line-item/category ?n]
|
||||
[(get-else $ ?li :order-line-item/item-name \"\") ?n2]
|
||||
[?li :order-line-item/total ?total]
|
||||
[?li :order-line-item/tax ?tax]
|
||||
[?li :order-line-item/discount ?discount]
|
||||
[(clj-time.coerce/to-date-time ?d) ?d2]
|
||||
[(auto-ap.time/localize ?d2) ?d3]
|
||||
[(auto-ap.time/unparse-local ?d3 auto-ap.time/normal-date) ?d4]
|
||||
]")
|
||||
|
||||
(def expected-deposits-query
|
||||
"[:find ?d4 ?t ?f
|
||||
:in $
|
||||
:where
|
||||
[?c :client/code \"%s\"]
|
||||
[?s :expected-deposit/client ?c]
|
||||
[?s :expected-deposit/total ?t]
|
||||
[?s :expected-deposit/fee ?f]
|
||||
[?s :expected-deposit/sales-date ?date]
|
||||
[(clj-time.coerce/to-date-time ?date) ?d2]
|
||||
[(auto-ap.time/localize ?d2) ?d3]
|
||||
[(auto-ap.time/unparse-local ?d3 auto-ap.time/normal-date) ?d4]
|
||||
]")
|
||||
|
||||
(def tenders-query
|
||||
"[:find ?d4 ?type ?p2 (sum ?total) (sum ?tip)
|
||||
:with ?charge
|
||||
:in $
|
||||
:where
|
||||
[?c :client/code \"%s\"]
|
||||
[?s :sales-order/client ?c]
|
||||
[?s :sales-order/charges ?charge]
|
||||
[?charge :charge/type-name ?type]
|
||||
[?charge :charge/total ?total]
|
||||
[?charge :charge/tip ?tip]
|
||||
[(get-else $ ?charge :charge/processor :na) ?ccp]
|
||||
[(get-else $ ?ccp :db/ident :na) ?p]
|
||||
[(name ?p) ?p2]
|
||||
[?s :sales-order/date ?date]
|
||||
[(clj-time.coerce/to-date-time ?date) ?d2]
|
||||
[(auto-ap.time/localize ?d2) ?d3]
|
||||
[(auto-ap.time/unparse-local ?d3 auto-ap.time/normal-date) ?d4]
|
||||
]")
|
||||
|
||||
(def refunds-query
|
||||
"[:find ?d4 ?t (sum ?total) (sum ?fee)
|
||||
:with ?r
|
||||
:in $
|
||||
:where
|
||||
[?r :sales-refund/client [:client/code \"%s\"]]
|
||||
[?r :sales-refund/total ?total]
|
||||
[?r :sales-refund/fee ?fee]
|
||||
[?r :sales-refund/date ?date]
|
||||
[?r :sales-refund/type ?t]
|
||||
[(clj-time.coerce/to-date-time ?date) ?d2]
|
||||
[(auto-ap.time/localize ?d2) ?d3]
|
||||
[(auto-ap.time/unparse-local ?d3 auto-ap.time/normal-date) ?d4]]")
|
||||
|
||||
|
||||
|
||||
(defn setup-sales-queries [context args _]
|
||||
(assert-admin (:id context))
|
||||
(let [{client-code :client/code} (d/pull (d/db conn) '[:client/code] (:client_id args))]
|
||||
(q/put-query (str (UUID/randomUUID))
|
||||
(format sales-summary-query client-code)
|
||||
(str "sales query for " client-code)
|
||||
(str client-code "-sales-summary")
|
||||
[:client/code client-code]
|
||||
)
|
||||
(q/put-query (str (UUID/randomUUID))
|
||||
(format sales-category-query client-code)
|
||||
(str "sales category query for " client-code)
|
||||
(str client-code "-sales-category")
|
||||
[:client/code client-code]
|
||||
)
|
||||
(q/put-query (str (UUID/randomUUID))
|
||||
(format expected-deposits-query client-code)
|
||||
(str "expected deposit query for " client-code)
|
||||
(str client-code "-expected-deposit")
|
||||
[:client/code client-code]
|
||||
)
|
||||
(q/put-query (str (UUID/randomUUID))
|
||||
(format tenders-query client-code)
|
||||
(str "tender query for " client-code)
|
||||
(str client-code "-tender")
|
||||
[:client/code client-code]
|
||||
)
|
||||
|
||||
(q/put-query (str (UUID/randomUUID))
|
||||
(format refunds-query client-code)
|
||||
(str "refunds query for " client-code)
|
||||
(str client-code "-refund")
|
||||
[:client/code client-code])
|
||||
|
||||
(let [sales-summary-id (:saved-query/guid (d/pull (d/db auto-ap.datomic/conn) [:saved-query/guid] [:saved-query/lookup-key (str client-code "-sales-summary")]))
|
||||
sales-category-id (:saved-query/guid (d/pull (d/db auto-ap.datomic/conn) [:saved-query/guid] [:saved-query/lookup-key (str client-code "-sales-category")]))
|
||||
expected-deposit-id (:saved-query/guid (d/pull (d/db auto-ap.datomic/conn) [:saved-query/guid] [:saved-query/lookup-key (str client-code "-expected-deposit")]))
|
||||
tender-id (:saved-query/guid (d/pull (d/db auto-ap.datomic/conn) [:saved-query/guid] [:saved-query/lookup-key (str client-code "-tender")]))
|
||||
refund-id (:saved-query/guid (d/pull (d/db auto-ap.datomic/conn) [:saved-query/guid] [:saved-query/lookup-key (str client-code "-refund")]))]
|
||||
{:message (str/join "\n"
|
||||
[
|
||||
(str "For " client-code ":")
|
||||
(str "Sales: " "https://app.integreatconsult.com/api/queries/" sales-summary-id "/results/json")
|
||||
(str "Sales Category: " "https://app.integreatconsult.com/api/queries/" sales-category-id "/results/json")
|
||||
(str "Expected Deposits: " "https://app.integreatconsult.com/api/queries/" expected-deposit-id "/results/json")
|
||||
(str "Tenders: " "https://app.integreatconsult.com/api/queries/" tender-id "/results/json")
|
||||
(str "Refund: " "https://app.integreatconsult.com/api/queries/" refund-id "/results/json")])})))
|
||||
|
||||
|
||||
(def objects
|
||||
{:location_match
|
||||
@@ -353,7 +488,10 @@
|
||||
(def mutations
|
||||
{:edit_client {:type :client
|
||||
:args {:edit_client {:type :edit_client}}
|
||||
:resolve :mutation/edit-client}})
|
||||
:resolve :mutation/edit-client}
|
||||
:setup_sales_queries {:type :message
|
||||
:args {:client_id {:type :id}}
|
||||
:resolve :mutation/setup-sales-queries}})
|
||||
|
||||
(def input-objects
|
||||
{:edit_location_match {:fields {:location {:type 'String}
|
||||
@@ -418,7 +556,8 @@
|
||||
|
||||
(def resolvers
|
||||
{:get-client get-client
|
||||
:mutation/edit-client edit-client})
|
||||
:mutation/edit-client edit-client
|
||||
:mutation/setup-sales-queries setup-sales-queries})
|
||||
|
||||
|
||||
(defn attach [schema]
|
||||
|
||||
@@ -40,13 +40,12 @@
|
||||
:user/name (:name profile)})
|
||||
]
|
||||
(log/info "authenticated as user" user)
|
||||
|
||||
;; TODO - these namespaces are not being transmitted/deserialized properly
|
||||
(if (and token user)
|
||||
(let [jwt (jwt/sign {:user (:name profile)
|
||||
:exp (time/plus (time/now) (time/days 30))
|
||||
:user/clients (map (fn [c]
|
||||
(dissoc c :client/bank-accounts :client/location-matches :client/forecasted-transactions :client/matches :client/week-a-debits :client/week-a-credits :client/week-b-debits :client/week-b-credits :client/signature-file :client/address :client/emails :client/square-auth-token :client/square-locations))
|
||||
(select-keys c [:client/code :db/id :client/name :client/locations]))
|
||||
(:user/clients user))
|
||||
:user/role (name (:user/role user))
|
||||
:user/name (:name profile)}
|
||||
|
||||
@@ -41,17 +41,27 @@
|
||||
(into [(d/db conn)] (clojure.edn/read-string (get query-params "args" "[]")))))))))
|
||||
|
||||
|
||||
(defn put-query [id body note]
|
||||
(s3/put-object :bucket-name (:data-bucket env)
|
||||
:key (str "queries/" id)
|
||||
:input-stream (io/make-input-stream (.getBytes body) {})
|
||||
:metadata {:content-type "application/text"
|
||||
:user-metadata {:note note}})
|
||||
{:body {:query body
|
||||
:id id
|
||||
:results-url (str "/api/queries/" id "/results")
|
||||
:csv-results-url (str "/api/queries/" id "/results/csv")
|
||||
:json-results-url (str "/api/queries/" id "/results/json")}})
|
||||
(defn put-query [guid body note & [lookup-key client]]
|
||||
(let [guid (if lookup-key
|
||||
(or (:saved-query/guid (d/pull (d/db conn) [:saved-query/guid] [:saved-query/lookup-key lookup-key]))
|
||||
guid)
|
||||
guid)]
|
||||
@(d/transact conn [(cond->
|
||||
{:saved-query/guid guid
|
||||
:saved-query/description note
|
||||
:saved-query/key (str "queries/" guid)}
|
||||
client (assoc :saved-query/client client)
|
||||
lookup-key (assoc :saved-query/lookup-key lookup-key))])
|
||||
(s3/put-object :bucket-name (:data-bucket env)
|
||||
:key (str "queries/" guid)
|
||||
:input-stream (io/make-input-stream (.getBytes body) {})
|
||||
:metadata {:content-type "application/text"
|
||||
:user-metadata {:note note}})
|
||||
{:body {:query body
|
||||
:id guid
|
||||
:results-url (str "/api/queries/" guid "/results")
|
||||
:csv-results-url (str "/api/queries/" guid "/results/csv")
|
||||
:json-results-url (str "/api/queries/" guid "/results/json")}}))
|
||||
|
||||
(def json-routes
|
||||
(context "/queries" []
|
||||
|
||||
@@ -24,50 +24,68 @@
|
||||
(defn auth-header
|
||||
([cob-session] (str "Bearer " cob-session)))
|
||||
|
||||
|
||||
(defn retry-thrice
|
||||
([x] (retry-thrice x 0))
|
||||
([x i]
|
||||
(try
|
||||
(x)
|
||||
(catch Exception e
|
||||
(if (>= i 3)
|
||||
(throw e)
|
||||
(do
|
||||
(Thread/sleep 5000)
|
||||
(retry-thrice x (inc i))))))))
|
||||
|
||||
(def other-config
|
||||
(if (:yodlee2-proxy-host env)
|
||||
{:proxy-host (:yodlee2-proxy-host env)
|
||||
:proxy-port (:yodlee2-proxy-port env)
|
||||
:retry-handler (fn [ex try-count http-context]
|
||||
:socket-timeout 60000
|
||||
:connection-timeout 60000
|
||||
:retry-handler (fn [ex _ _]
|
||||
(log/error "yodlee Error." ex)
|
||||
false)}
|
||||
{:retry-handler (fn [ex try-count http-context]
|
||||
{:retry-handler (fn [ex _ _]
|
||||
(log/error "yodlee Error." ex)
|
||||
false)}))
|
||||
false)
|
||||
:socket-timeout 60000
|
||||
:connection-timeout 60000}))
|
||||
|
||||
(def base-headers {"Api-Version" "1.1"
|
||||
"Content-Type" "application/json"})
|
||||
|
||||
(defn login-cobrand []
|
||||
(-> (str (:yodlee2-base-url env) "/auth/token")
|
||||
(client/post (merge {:headers (assoc base-headers
|
||||
"loginName" (:yodlee2-admin-user env)
|
||||
"Content-Type" "application/x-www-form-urlencoded")
|
||||
:body (str "clientId=" (:yodlee2-client-id env) " &secret=" (:yodlee2-client-secret env))
|
||||
:as :json}
|
||||
other-config)
|
||||
)
|
||||
:body
|
||||
:token
|
||||
:accessToken))
|
||||
(retry-thrice
|
||||
(fn []
|
||||
(-> (str (:yodlee2-base-url env) "/auth/token")
|
||||
(client/post (merge {:headers (assoc base-headers
|
||||
"loginName" (:yodlee2-admin-user env)
|
||||
"Content-Type" "application/x-www-form-urlencoded")
|
||||
:body (str "clientId=" (:yodlee2-client-id env) " &secret=" (:yodlee2-client-secret env))
|
||||
:as :json}
|
||||
other-config)
|
||||
)
|
||||
:body
|
||||
:token
|
||||
:accessToken))))
|
||||
|
||||
(defn login-user [client-code]
|
||||
(log/info "logging in as " client-code)
|
||||
(-> (str (:yodlee2-base-url env) "/auth/token")
|
||||
(client/post (merge {:headers (assoc base-headers
|
||||
"loginName" (if (<= (count client-code) 3)
|
||||
(str client-code client-code)
|
||||
client-code)
|
||||
"Content-Type" "application/x-www-form-urlencoded")
|
||||
:body (str "clientId=" (:yodlee2-client-id env) " &secret=" (:yodlee2-client-secret env))
|
||||
:as :json}
|
||||
other-config)
|
||||
)
|
||||
:body
|
||||
:token
|
||||
:accessToken))
|
||||
(retry-thrice
|
||||
(fn []
|
||||
(log/info "logging in as " client-code)
|
||||
(-> (str (:yodlee2-base-url env) "/auth/token")
|
||||
(client/post (merge {:headers (assoc base-headers
|
||||
"loginName" (if (<= (count client-code) 3)
|
||||
(str client-code client-code)
|
||||
client-code)
|
||||
"Content-Type" "application/x-www-form-urlencoded")
|
||||
:body (str "clientId=" (:yodlee2-client-id env) " &secret=" (:yodlee2-client-secret env))
|
||||
:as :json}
|
||||
other-config)
|
||||
)
|
||||
:body
|
||||
:token
|
||||
:accessToken))))
|
||||
|
||||
(defn get-accounts [client-code ]
|
||||
(let [cob-session (login-user (client-code->login client-code))]
|
||||
@@ -93,14 +111,16 @@
|
||||
[])))
|
||||
|
||||
(defn get-provider-accounts [client-code ]
|
||||
(log/info "logging in user " client-code)
|
||||
(let [cob-session (login-user (client-code->login client-code))]
|
||||
(-> (str (:yodlee2-base-url env) "/providerAccounts")
|
||||
(-> (client/get (merge {:headers (merge base-headers {"Authorization" (auth-header cob-session )})
|
||||
:as :json}
|
||||
other-config))
|
||||
:body
|
||||
:providerAccount))))
|
||||
(retry-thrice
|
||||
(fn []
|
||||
(log/info "logging in user " client-code)
|
||||
(let [cob-session (login-user (client-code->login client-code))]
|
||||
(-> (str (:yodlee2-base-url env) "/providerAccounts")
|
||||
(-> (client/get (merge {:headers (merge base-headers {"Authorization" (auth-header cob-session )})
|
||||
:as :json}
|
||||
other-config))
|
||||
:body
|
||||
:providerAccount))))))
|
||||
|
||||
|
||||
|
||||
@@ -323,7 +343,6 @@
|
||||
|
||||
|
||||
(defn reauthenticate [client-code pa data]
|
||||
(println client-code)
|
||||
(try
|
||||
(-> (str (:yodlee2-base-url env) "/providerAccounts?providerAccountIds=" pa)
|
||||
|
||||
|
||||
135
src/clj/user.clj
135
src/clj/user.clj
@@ -15,7 +15,7 @@
|
||||
[clj-time.core :as t]
|
||||
[clojure.java.io :as io]
|
||||
[clojure.string :as str]
|
||||
[auto-ap.routes.queries :as q]
|
||||
|
||||
[amazonica.aws.s3 :as s3])
|
||||
(:import [org.apache.commons.io.input BOMInputStream]
|
||||
java.util.UUID))
|
||||
@@ -477,139 +477,6 @@
|
||||
(println "failed " e)))
|
||||
(async/<!! (async/into [] output-chan)))))
|
||||
|
||||
(def sales-summary-query
|
||||
"[:find ?d4 (sum ?total) (sum ?tax) (sum ?tip) (sum ?service-charge) (sum ?discount) (sum ?returns)
|
||||
:with ?s
|
||||
:in $
|
||||
:where
|
||||
[?s :sales-order/client [:client/code \"%s\"]]
|
||||
[?s :sales-order/date ?d]
|
||||
[?s :sales-order/total ?total]
|
||||
[?s :sales-order/tax ?tax]
|
||||
[?s :sales-order/tip ?tip]
|
||||
[?s :sales-order/service-charge ?service-charge]
|
||||
[?s :sales-order/returns ?returns]
|
||||
[?s :sales-order/discount ?discount]
|
||||
[(clj-time.coerce/to-date-time ?d) ?d2]
|
||||
[(auto-ap.time/localize ?d2) ?d3]
|
||||
[(auto-ap.time/unparse-local ?d3 auto-ap.time/normal-date) ?d4]
|
||||
]")
|
||||
|
||||
(def sales-category-query
|
||||
"[:find ?d4 ?n ?n2 (sum ?total) (sum ?tax) (sum ?discount)
|
||||
:with ?s ?li
|
||||
:in $
|
||||
:where
|
||||
[?s :sales-order/client [:client/code \"%s\"]]
|
||||
[?s :sales-order/date ?d]
|
||||
[?s :sales-order/line-items ?li]
|
||||
[?li :order-line-item/category ?n]
|
||||
[(get-else $ ?li :order-line-item/item-name \"\") ?n2]
|
||||
[?li :order-line-item/total ?total]
|
||||
[?li :order-line-item/tax ?tax]
|
||||
[?li :order-line-item/discount ?discount]
|
||||
[(clj-time.coerce/to-date-time ?d) ?d2]
|
||||
[(auto-ap.time/localize ?d2) ?d3]
|
||||
[(auto-ap.time/unparse-local ?d3 auto-ap.time/normal-date) ?d4]
|
||||
]")
|
||||
|
||||
(def expected-deposits-query
|
||||
"[:find ?d4 ?t ?f
|
||||
:in $
|
||||
:where
|
||||
[?c :client/code \"%s\"]
|
||||
[?s :expected-deposit/client ?c]
|
||||
[?s :expected-deposit/total ?t]
|
||||
[?s :expected-deposit/fee ?f]
|
||||
[?s :expected-deposit/sales-date ?date]
|
||||
[(clj-time.coerce/to-date-time ?date) ?d2]
|
||||
[(auto-ap.time/localize ?d2) ?d3]
|
||||
[(auto-ap.time/unparse-local ?d3 auto-ap.time/normal-date) ?d4]
|
||||
]")
|
||||
|
||||
(def tenders-query
|
||||
"[:find ?d4 ?type ?p2 (sum ?total) (sum ?tip)
|
||||
:with ?charge
|
||||
:in $
|
||||
:where
|
||||
[?c :client/code \"%s\"]
|
||||
[?s :sales-order/client ?c]
|
||||
[?s :sales-order/charges ?charge]
|
||||
[?charge :charge/type-name ?type]
|
||||
[?charge :charge/total ?total]
|
||||
[?charge :charge/tip ?tip]
|
||||
[(get-else $ ?charge :charge/processor :na) ?ccp]
|
||||
[(get-else $ ?ccp :db/ident :na) ?p]
|
||||
[(name ?p) ?p2]
|
||||
[?s :sales-order/date ?date]
|
||||
[(clj-time.coerce/to-date-time ?date) ?d2]
|
||||
[(auto-ap.time/localize ?d2) ?d3]
|
||||
[(auto-ap.time/unparse-local ?d3 auto-ap.time/normal-date) ?d4]
|
||||
]")
|
||||
|
||||
(def refunds-query
|
||||
"[:find ?d4 ?t (sum ?total) (sum ?fee)
|
||||
:with ?r
|
||||
:in $
|
||||
:where
|
||||
[?r :sales-refund/client [:client/code \"%s\"]]
|
||||
[?r :sales-refund/total ?total]
|
||||
[?r :sales-refund/fee ?fee]
|
||||
[?r :sales-refund/date ?date]
|
||||
[?r :sales-refund/type ?t]
|
||||
[(clj-time.coerce/to-date-time ?date) ?d2]
|
||||
[(auto-ap.time/localize ?d2) ?d3]
|
||||
[(auto-ap.time/unparse-local ?d3 auto-ap.time/normal-date) ?d4]]")
|
||||
|
||||
(defn setup-sales-queries [client-code]
|
||||
(let [sales-summary-id (or (first (find-queries [client-code "service-charge"]))
|
||||
(str (UUID/randomUUID)))
|
||||
sales-category-id (or (first (find-queries [client-code "item-name"]))
|
||||
(str (UUID/randomUUID)))
|
||||
expected-deposit-id (or (first (find-queries [client-code "expected-deposit"]))
|
||||
(str (UUID/randomUUID)))
|
||||
tender-id (or (first (find-queries [client-code ":charge"]))
|
||||
(str (UUID/randomUUID)))
|
||||
refund-id (or (first (find-queries [client-code "sales-refund"]))
|
||||
(str (UUID/randomUUID)))]
|
||||
(map (comp :json-results-url :body)
|
||||
[(q/put-query sales-summary-id
|
||||
(format sales-summary-query client-code)
|
||||
(str "sales query for " client-code)
|
||||
)
|
||||
(q/put-query sales-category-id
|
||||
(format sales-category-query client-code)
|
||||
(str "sales category query for " client-code)
|
||||
)
|
||||
(q/put-query expected-deposit-id
|
||||
(format expected-deposits-query client-code)
|
||||
(str "expected deposit query for " client-code)
|
||||
)
|
||||
(q/put-query tender-id
|
||||
(format tenders-query client-code)
|
||||
(str "tender query for " client-code))
|
||||
|
||||
(q/put-query refund-id
|
||||
(format refunds-query client-code)
|
||||
(str "refunds query for " client-code)
|
||||
)])))
|
||||
|
||||
|
||||
(defn print-sales-queries [client-code]
|
||||
(let [sales-summary-id (first (find-queries [client-code "service-charge"]))
|
||||
sales-category-id (first (find-queries [client-code "item-name"]))
|
||||
expected-deposit-id (first (find-queries [client-code "expected-deposit"]))
|
||||
tender-id (first (find-queries [client-code ":charge"]))
|
||||
refund-id (first (find-queries [client-code "sales-refund"]))]
|
||||
|
||||
(println "For" client-code ":")
|
||||
(println "Sales: " (str "https://app.integreatconsult.com/api/queries/" sales-summary-id "/results/json"))
|
||||
(println "Sales Category: " (str "https://app.integreatconsult.com/api/queries/" sales-category-id "/results/json"))
|
||||
(println "Expected Deposits: " (str "https://app.integreatconsult.com/api/queries/" expected-deposit-id "/results/json"))
|
||||
(println "Tenders: " (str "https://app.integreatconsult.com/api/queries/" tender-id "/results/json"))
|
||||
(println "Refund: " (str "https://app.integreatconsult.com/api/queries/" refund-id "/results/json"))
|
||||
(println "")))
|
||||
|
||||
|
||||
(defn historical-load-sales [client-code days]
|
||||
(let [client (d/pull (d/db auto-ap.datomic/conn)
|
||||
|
||||
@@ -3,9 +3,11 @@
|
||||
[clojure.string :as str]
|
||||
[re-frame.core :as re-frame]
|
||||
[auto-ap.views.pages.admin.clients.form :as form]
|
||||
[auto-ap.views.utils :refer [action-cell-width date->str]]
|
||||
[auto-ap.views.utils :refer [action-cell-width date->str with-user]]
|
||||
[auto-ap.views.components.grid :as grid]
|
||||
[auto-ap.views.components.buttons :as buttons]))
|
||||
[auto-ap.views.components.modal :as modal]
|
||||
[auto-ap.views.components.buttons :as buttons]
|
||||
[auto-ap.status :as status]))
|
||||
|
||||
(re-frame/reg-sub
|
||||
::specific-params
|
||||
@@ -17,6 +19,28 @@
|
||||
(fn [{:keys [db]} [_ p]]
|
||||
{:db (assoc db ::params p)}))
|
||||
|
||||
(re-frame/reg-event-fx
|
||||
::sales-queries-setup
|
||||
(fn [_ [_ results]]
|
||||
{:dispatch [::modal/modal-requested {:title "Sales Queries"
|
||||
:body [:div [:pre (:message (:setup-sales-queries results))]]}]}))
|
||||
|
||||
(re-frame/reg-event-fx
|
||||
::setup-sales-queries
|
||||
[with-user]
|
||||
(fn [{:keys [user]} [_ client-id]]
|
||||
{:graphql
|
||||
{:token user
|
||||
:owns-state {:multi ::setup-sales-queries
|
||||
:which client-id}
|
||||
:query-obj {:venia/operation {:operation/type :mutation
|
||||
:operation/name "SetupSalesQueries"}
|
||||
:venia/queries [{:query/data [:setup-sales-queries
|
||||
{:client-id client-id}
|
||||
[:message]]}]}
|
||||
:on-success [::sales-queries-setup]}}
|
||||
))
|
||||
|
||||
(re-frame/reg-sub
|
||||
::params
|
||||
:<- [::specific-params]
|
||||
@@ -26,33 +50,37 @@
|
||||
|
||||
|
||||
(defn clients-table [{:keys [page status]}]
|
||||
[grid/grid {:on-params-change (fn [p]
|
||||
(re-frame/dispatch [::params-changed p]))
|
||||
:status status
|
||||
:params @(re-frame/subscribe [::params])
|
||||
:column-count 5}
|
||||
[grid/controls page]
|
||||
[grid/table {:fullwidth true}
|
||||
[grid/header
|
||||
[grid/row {}
|
||||
[grid/header-cell {} "Name"]
|
||||
[grid/header-cell {:style {:width "20em"}} "Code"]
|
||||
[grid/header-cell {} "Locations"]
|
||||
[grid/header-cell {} "Locked Until"]
|
||||
[grid/header-cell {} "Email"]
|
||||
[grid/header-cell {:style {:width (action-cell-width 1)}}]]
|
||||
]
|
||||
[grid/body
|
||||
(for [{:keys [id name email locked-until code locations] :as c} (:data page)]
|
||||
^{:key (str name "-" id )}
|
||||
[grid/row {:id id}
|
||||
[grid/cell {} name]
|
||||
[grid/cell {} code]
|
||||
[grid/cell {} (str/join ", " locations)]
|
||||
[grid/cell {} [:div.tag (or (some-> locked-until date->str)
|
||||
"Not locked"
|
||||
(let [states @(re-frame/subscribe [::status/multi ::setup-sales-queries])]
|
||||
[grid/grid {:on-params-change (fn [p]
|
||||
(re-frame/dispatch [::params-changed p]))
|
||||
:status status
|
||||
:params @(re-frame/subscribe [::params])
|
||||
:column-count 5}
|
||||
[grid/controls page]
|
||||
[grid/table {:fullwidth true}
|
||||
[grid/header
|
||||
[grid/row {}
|
||||
[grid/header-cell {} "Name"]
|
||||
[grid/header-cell {:style {:width "20em"}} "Code"]
|
||||
[grid/header-cell {} "Locations"]
|
||||
[grid/header-cell {} "Locked Until"]
|
||||
[grid/header-cell {} "Email"]
|
||||
[grid/header-cell {:style {:width (action-cell-width 2)}}]]
|
||||
]
|
||||
[grid/body
|
||||
(for [{:keys [id name email locked-until code locations]} (:data page)]
|
||||
^{:key (str name "-" id )}
|
||||
[grid/row {:id id}
|
||||
[grid/cell {} name]
|
||||
[grid/cell {} code]
|
||||
[grid/cell {} (str/join ", " locations)]
|
||||
[grid/cell {} [:div.tag (or (some-> locked-until date->str)
|
||||
"Not locked"
|
||||
|
||||
)]]
|
||||
[grid/cell {} email]
|
||||
[grid/cell {} [buttons/fa-icon {:event [::form/editing id]
|
||||
:icon :fa-pencil}]]])]]])
|
||||
)]]
|
||||
[grid/cell {} email]
|
||||
[grid/cell {} [:div.buttons [buttons/fa-icon {:event [::setup-sales-queries id]
|
||||
:class (status/class-for (get states id))
|
||||
:icon :fa-dollar}]
|
||||
[buttons/fa-icon {:event [::form/editing id]
|
||||
:icon :fa-pencil}]]]])]]]))
|
||||
|
||||
Reference in New Issue
Block a user