Should fix most of the authentication issues
This commit is contained in:
@@ -4,6 +4,10 @@
|
|||||||
[clj-time.format :as f]
|
[clj-time.format :as f]
|
||||||
[datomic.api :as dc]))
|
[datomic.api :as dc]))
|
||||||
|
|
||||||
|
;; TODO WILL NOT WORK IN DATOMIC CLOUD
|
||||||
|
(defn entid [db i]
|
||||||
|
(dc/entid db i))
|
||||||
|
|
||||||
#_{:clj-kondo/ignore [:clojure-lsp/unused-public-var]}
|
#_{:clj-kondo/ignore [:clojure-lsp/unused-public-var]}
|
||||||
(defn dollars-0? [amt]
|
(defn dollars-0? [amt]
|
||||||
(< -0.001 amt 0.001))
|
(< -0.001 amt 0.001))
|
||||||
@@ -61,3 +65,39 @@
|
|||||||
(.toInstant)
|
(.toInstant)
|
||||||
(.atZone (java.time.ZoneId/of "US/Pacific"))
|
(.atZone (java.time.ZoneId/of "US/Pacific"))
|
||||||
(.get java.time.temporal.ChronoField/DAY_OF_MONTH)))
|
(.get java.time.temporal.ChronoField/DAY_OF_MONTH)))
|
||||||
|
|
||||||
|
(defn scan-invoices [db clients start end]
|
||||||
|
(for [c clients
|
||||||
|
:let [c (entid db c)]
|
||||||
|
r (seq (dc/index-range db
|
||||||
|
:invoice/client+date
|
||||||
|
[c (or start #inst "2001-01-01T08:00:00.000-00:00") ]
|
||||||
|
[c (or end #inst "2030-03-05T08:00:00.000-00:00") ]))]
|
||||||
|
[(:e r) (first (:v r)) (second (:v r))]))
|
||||||
|
|
||||||
|
(defn scan-transactions [db clients start end]
|
||||||
|
(for [c clients
|
||||||
|
:let [c (entid db c)]
|
||||||
|
r (seq (dc/index-range db
|
||||||
|
:transaction/client+date
|
||||||
|
[c (or start #inst "2001-01-01T08:00:00.000-00:00") ]
|
||||||
|
[c (or end #inst "2030-03-05T08:00:00.000-00:00") ]))]
|
||||||
|
[(:e r) (first (:v r)) (second (:v r))]))
|
||||||
|
|
||||||
|
(defn scan-ledger [db clients start end]
|
||||||
|
(for [c clients
|
||||||
|
:let [c (entid db c)]
|
||||||
|
r (seq (dc/index-range db
|
||||||
|
:journal-entry/client+date
|
||||||
|
[c (or start #inst "2001-01-01T08:00:00.000-00:00") ]
|
||||||
|
[c (or end #inst "2030-03-05T08:00:00.000-00:00") ]))]
|
||||||
|
[(:e r) (first (:v r)) (second (:v r))]))
|
||||||
|
|
||||||
|
(defn scan-payments [db clients start end]
|
||||||
|
(for [c clients
|
||||||
|
:let [c (entid db c)]
|
||||||
|
r (seq (dc/index-range db
|
||||||
|
:payment/client+date
|
||||||
|
[c (or start #inst "2001-01-01T08:00:00.000-00:00") ]
|
||||||
|
[c (or end #inst "2030-03-05T08:00:00.000-00:00") ]))]
|
||||||
|
[(:e r) (first (:v r)) (second (:v r))]))
|
||||||
|
|||||||
@@ -36,9 +36,6 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
(defn regenerate-literals []
|
(defn regenerate-literals []
|
||||||
(require 'com.github.ivarref.gen-fn)
|
(require 'com.github.ivarref.gen-fn)
|
||||||
(spit
|
(spit
|
||||||
|
|||||||
11
package-lock.json
generated
11
package-lock.json
generated
@@ -14,6 +14,7 @@
|
|||||||
"dropzone": "^4.3.0",
|
"dropzone": "^4.3.0",
|
||||||
"flowbite": "^1.6.5",
|
"flowbite": "^1.6.5",
|
||||||
"minisearch": "^3.0.2",
|
"minisearch": "^3.0.2",
|
||||||
|
"pako": "^2.1.0",
|
||||||
"prop-types": "^15.7.2",
|
"prop-types": "^15.7.2",
|
||||||
"react": "^17.0.1",
|
"react": "^17.0.1",
|
||||||
"react-dom": "^17.0.1",
|
"react-dom": "^17.0.1",
|
||||||
@@ -1674,6 +1675,11 @@
|
|||||||
"node": ">=6"
|
"node": ">=6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/pako": {
|
||||||
|
"version": "2.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/pako/-/pako-2.1.0.tgz",
|
||||||
|
"integrity": "sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug=="
|
||||||
|
},
|
||||||
"node_modules/path-exists": {
|
"node_modules/path-exists": {
|
||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
|
||||||
@@ -4159,6 +4165,11 @@
|
|||||||
"integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
|
"integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"pako": {
|
||||||
|
"version": "2.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/pako/-/pako-2.1.0.tgz",
|
||||||
|
"integrity": "sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug=="
|
||||||
|
},
|
||||||
"path-exists": {
|
"path-exists": {
|
||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
"dropzone": "^4.3.0",
|
"dropzone": "^4.3.0",
|
||||||
"flowbite": "^1.6.5",
|
"flowbite": "^1.6.5",
|
||||||
"minisearch": "^3.0.2",
|
"minisearch": "^3.0.2",
|
||||||
|
"pako": "^2.1.0",
|
||||||
"prop-types": "^15.7.2",
|
"prop-types": "^15.7.2",
|
||||||
"react": "^17.0.1",
|
"react": "^17.0.1",
|
||||||
"react-dom": "^17.0.1",
|
"react-dom": "^17.0.1",
|
||||||
|
|||||||
@@ -1782,4 +1782,30 @@
|
|||||||
:db/valueType :db.type/tuple
|
:db/valueType :db.type/tuple
|
||||||
:db/doc "The recommended vendor, account, and transaction count, and whether seen by the client,"
|
:db/doc "The recommended vendor, account, and transaction count, and whether seen by the client,"
|
||||||
:db/tupleTypes [:db.type/ref :db.type/ref :db.type/long :db.type/boolean]
|
:db/tupleTypes [:db.type/ref :db.type/ref :db.type/long :db.type/boolean]
|
||||||
:db/cardinality :db.cardinality/many}]
|
:db/cardinality :db.cardinality/many}
|
||||||
|
|
||||||
|
{:db/ident :invoice/client+date
|
||||||
|
:db/valueType :db.type/tuple
|
||||||
|
:db/tupleAttrs [ :invoice/client :invoice/date]
|
||||||
|
:db/cardinality :db.cardinality/one
|
||||||
|
:db/index true}
|
||||||
|
|
||||||
|
{:db/ident :transaction/client+date
|
||||||
|
:db/valueType :db.type/tuple
|
||||||
|
:db/tupleAttrs [ :transaction/client :transaction/date]
|
||||||
|
:db/cardinality :db.cardinality/one
|
||||||
|
:db/index true}
|
||||||
|
|
||||||
|
{:db/ident :journal-entry/client+date
|
||||||
|
:db/valueType :db.type/tuple
|
||||||
|
:db/tupleAttrs [ :journal-entry/client :journal-entry/date]
|
||||||
|
:db/cardinality :db.cardinality/one
|
||||||
|
:db/index true}
|
||||||
|
|
||||||
|
{:db/ident :payment/client+date
|
||||||
|
:db/valueType :db.type/tuple
|
||||||
|
:db/tupleAttrs [ :payment/client :payment/date]
|
||||||
|
:db/cardinality :db.cardinality/one
|
||||||
|
:db/index true}]
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
168
scratch-sessions/fix-page-performance.repl
Normal file
168
scratch-sessions/fix-page-performance.repl
Normal file
@@ -0,0 +1,168 @@
|
|||||||
|
;; This buffer is for Clojure experiments and evaluation.
|
||||||
|
|
||||||
|
;; Press C-j to evaluate the last expression.
|
||||||
|
|
||||||
|
;; You can also press C-u C-j to evaluate the expression and pretty-print its result.
|
||||||
|
|
||||||
|
|
||||||
|
'{:query ,
|
||||||
|
:phases [{:sched (([(ground $__in__2) ?start-date] [?e :invoice/date ?date] [(>= ?date ?start-date)] [(ground $__in__3) [?xx ...]] [?e :invoice/client ?xx] [?e :invoice/client] [?e :invoice/date ?sort-default])), :clauses [{:clause [(ground $__in__2) ?start-date], :rows-in 0, :rows-out 1, :binds-in (), :binds-out [?start-date], :expansion 1} {:clause [?e :invoice/date ?date], :rows-in 1, :rows-out 9656, :binds-in [?start-date], :binds-out [?date ?start-date ?e], :preds ([(>= ?date ?start-date)]), :expansion 9655, :warnings {:unbound-vars #{?date ?e}}} {:clause [(ground $__in__3) [?xx ...]], :rows-in 9656, :rows-out 1303560, :binds-in [?date ?start-date ?e], :binds-out [?xx ?e], :expansion 1293904} {:clause [?e :invoice/client ?xx], :rows-in 1303560, :rows-out 9656, :binds-in [?xx ?e], :binds-out [?e]} {:clause [?e :invoice/client], :rows-in 9656, :rows-out 9656, :binds-in [?e], :binds-out [?e]} {:clause [?e :invoice/date ?sort-default], :rows-in 9656, :rows-out 9656, :binds-in [?e], :binds-out [?sort-default ?e]}]}]}
|
||||||
|
;; => {:query
|
||||||
|
;; {:find [?sort-default ?e],
|
||||||
|
;; :in [$ ?start-date [?xx ...]],
|
||||||
|
;; :where
|
||||||
|
;; [[?e :invoice/date ?date]
|
||||||
|
;; [(>= ?date ?start-date)]
|
||||||
|
;; [?e :invoice/client ?xx]
|
||||||
|
;; [?e :invoice/client]
|
||||||
|
;; [?e :invoice/date ?sort-default]]},
|
||||||
|
;; :phases
|
||||||
|
;; [{:sched
|
||||||
|
;; (([(ground $__in__2) ?start-date]
|
||||||
|
;; [?e :invoice/date ?date]
|
||||||
|
;; [(>= ?date ?start-date)]
|
||||||
|
;; [(ground $__in__3) [?xx ...]]
|
||||||
|
;; [?e :invoice/client ?xx]
|
||||||
|
;; [?e :invoice/client]
|
||||||
|
;; [?e :invoice/date ?sort-default])),
|
||||||
|
;; :clauses
|
||||||
|
;; [{:clause [(ground $__in__2) ?start-date],
|
||||||
|
;; :rows-in 0,
|
||||||
|
;; :rows-out 1,
|
||||||
|
;; :binds-in (),
|
||||||
|
;; :binds-out [?start-date],
|
||||||
|
;; :expansion 1}
|
||||||
|
;; {:clause [?e :invoice/date ?date],
|
||||||
|
;; :rows-in 1,
|
||||||
|
;; :rows-out 9656,
|
||||||
|
;; :binds-in [?start-date],
|
||||||
|
;; :binds-out [?date ?start-date ?e],
|
||||||
|
;; :preds ([(>= ?date ?start-date)]),
|
||||||
|
;; :expansion 9655,
|
||||||
|
;; :warnings {:unbound-vars #{?date ?e}}}
|
||||||
|
;; {:clause [(ground $__in__3) [?xx ...]],
|
||||||
|
;; :rows-in 9656,
|
||||||
|
;; :rows-out 1303560,
|
||||||
|
;; :binds-in [?date ?start-date ?e],
|
||||||
|
;; :binds-out [?xx ?e],
|
||||||
|
;; :expansion 1293904}
|
||||||
|
;; {:clause [?e :invoice/client ?xx],
|
||||||
|
;; :rows-in 1303560,
|
||||||
|
;; :rows-out 9656,
|
||||||
|
;; :binds-in [?xx ?e],
|
||||||
|
;; :binds-out [?e]}
|
||||||
|
;; {:clause [?e :invoice/client],
|
||||||
|
;; :rows-in 9656,
|
||||||
|
;; :rows-out 9656,
|
||||||
|
;; :binds-in [?e],
|
||||||
|
;; :binds-out [?e]}
|
||||||
|
;; {:clause [?e :invoice/date ?sort-default],
|
||||||
|
;; :rows-in 9656,
|
||||||
|
;; :rows-out 9656,
|
||||||
|
;; :binds-in [?e],
|
||||||
|
;; :binds-out [?sort-default ?e]}]}]}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
(time
|
||||||
|
(count
|
||||||
|
(observable-query
|
||||||
|
{:query {:find '[?sort-default ?e],
|
||||||
|
:in '[$ [?xx ...]],
|
||||||
|
:where '[[(untuple ?xx) [?target-date ?target-client]]
|
||||||
|
[(tuple #inst "2030-01-01" ?target-client) ?xx2]
|
||||||
|
[?e :invoice/date+client ?dc]
|
||||||
|
#_[(untuple)]
|
||||||
|
[(>= ?dc ?xx)]
|
||||||
|
[(<= ?dc ?xx2)]
|
||||||
|
[(untuple ?dc) [?sort-default]]
|
||||||
|
#_[?e :invoice/date ?date]
|
||||||
|
#_[(>= ?date ?start-date)]
|
||||||
|
#_[?e :invoice/client ?xx]
|
||||||
|
|
||||||
|
#_[?e :invoice/date ?sort-default]]}
|
||||||
|
:args [(dc/db conn) g]})))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
(defn recent-invoices [clients start end]
|
||||||
|
(for [ c clients
|
||||||
|
r (seq (dc/index-range (dc/db conn)
|
||||||
|
:invoice/client+date
|
||||||
|
[c (or start #inst "2001-01-01T08:00:00.000-00:00") ]
|
||||||
|
[c (or end #inst "2030-03-05T08:00:00.000-00:00") ]))]
|
||||||
|
(:e r)))
|
||||||
|
|
||||||
|
(recent-invoices all-clients
|
||||||
|
#inst "2023-03-05T08:00:00.000-00:00"
|
||||||
|
#inst "2050-03-05T08:00:00.000-00:00")
|
||||||
|
|
||||||
|
(count
|
||||||
|
(dc/query {:query '[:find ?e
|
||||||
|
:in $ [?clients ?start ?end]
|
||||||
|
:where [(auto-ap.datomic.invoices/recent-invoices ?clients ?start ?end) [?e ...]]]
|
||||||
|
:args [(dc/db conn)
|
||||||
|
[all-clients
|
||||||
|
#inst "2023-03-05T08:00:00.000-00:00"
|
||||||
|
nil]]}
|
||||||
|
))
|
||||||
|
|
||||||
|
(time
|
||||||
|
(count
|
||||||
|
(for [ c all-clients
|
||||||
|
r (seq (dc/index-range (dc/db conn)
|
||||||
|
:invoice/client+date
|
||||||
|
[c #inst "2023-03-05T08:00:00.000-00:00" ]
|
||||||
|
[c #inst "2030-03-05T08:00:00.000-00:00" ]))]
|
||||||
|
r)))
|
||||||
|
|
||||||
|
(take 500 (dc/index-range (dc/db conn)
|
||||||
|
:invoice/client+date
|
||||||
|
[17592186046356 #inst "2021-03-05T08:00:00.000-00:00" ]
|
||||||
|
[17592186046356 #inst "2053-03-05T08:00:00.000-00:00" ]
|
||||||
|
))
|
||||||
|
|
||||||
|
(def g
|
||||||
|
(map vector (repeat #inst "2023-03-05T08:00:00.000-00:00")
|
||||||
|
))
|
||||||
|
|
||||||
|
(def all-clients [17592186046356 17592186046363 17592186046366 17592186046371 17592186046373 17592186046378 17592186046380 17592186046385 17592186046394 17592186046397 17592186046400 17592186046404 17592186046409 17592186046415 17592186046422 17592186046428 17592186046437 17592186046447 17592186046456 17592186046465 17592186046472 17592186046478 17592186046491 17592186046499 17592186046513 17592186046520 17592186109023 17592193806897 17592195665346 17592196580407 17592203465691 17592204394806 17592219470393 17592219675333 17592221275294 17592232545948 17592232555238 17592232577980 17592232577988 17592232808650 17592232886729 17592232886786 17592232886793 17592232886797 17592232958090 17592233076577 17592233144301 17592233431334 17592233431814 17592234230520 17592234448526 17592234700485 17592234806481 17592234851859 17592235003983 17592235068155 17592235068158 17592235074859 17592235305451 17592235810873 17592235922068 17592236113837 17592236349303 17592236461666 17592236868866 17592236868871 17592238607837 17592238708423 17592238708558 17592241193003 17592242514773 17592242874891 17592243928280 17592244691542 17592244691558 17592244761680 17592245006804 17592245184339 17592246196802 17592247419073 17592247419185 17592247425545 17592249936256 17592249973733 17592250176578 17592250210564 17592250210567 17592250777772 17592250777854 17592253249909 17592257647588 17592258011361 17592258246710 17592258866422 17592260775415 17592262632255 17592264489873 17592264560519 17592265120447 17592271573602 17592271576404 17592273679867 17592275987623 17592275995130 17592275995135 17592276037255 17592277469850 17592278756108 17592280134939 17592281881509 17592284920305 17592285467793 17592286618015 17592288587524 17592289178758 17592289631589 17592290322936 17592291273963 17592291296031 17592291325248 17592291325326 17592291325452 17592291325766 17592291325864 17592291325954 17592291326043 17592291326115 17592291620408 17592292122045 17592294315344 17592295112116 17592296909432 17592296909449 17592296909452 17592297811962])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
(do
|
||||||
|
(auto-ap.datomic/audit-transact-batch (->> (dc/q '[:find ?e ?c
|
||||||
|
:in $
|
||||||
|
:where [?e :invoice/client ?c]]
|
||||||
|
(dc/db conn)
|
||||||
|
)
|
||||||
|
(map (fn [[i c]]
|
||||||
|
{:db/id i
|
||||||
|
:invoice/client c})))
|
||||||
|
|
||||||
|
{:user/name "hydrate-tuples"})
|
||||||
|
(auto-ap.datomic/audit-transact-batch (->> (dc/q '[:find ?e ?c
|
||||||
|
:in $
|
||||||
|
:where [?e :transaction/client ?c]]
|
||||||
|
(dc/db conn)
|
||||||
|
)
|
||||||
|
(map (fn [[i c]]
|
||||||
|
{:db/id i
|
||||||
|
:transaction/client c})))
|
||||||
|
|
||||||
|
{:user/name "hydrate-tuples"})
|
||||||
|
|
||||||
|
(auto-ap.datomic/audit-transact-batch (->> (dc/q '[:find ?e ?c
|
||||||
|
:in $
|
||||||
|
:where [?e :journal-entry/client ?c]]
|
||||||
|
(dc/db conn)
|
||||||
|
)
|
||||||
|
(map (fn [[i c]]
|
||||||
|
{:db/id i
|
||||||
|
:journal-entry/client c})))
|
||||||
|
|
||||||
|
{:user/name "hydrate-tuples"})
|
||||||
|
|
||||||
|
)
|
||||||
@@ -19,7 +19,8 @@
|
|||||||
[mount.core :as mount]
|
[mount.core :as mount]
|
||||||
[clojure.java.io :as io]
|
[clojure.java.io :as io]
|
||||||
[datomic.db :refer [id-literal]]
|
[datomic.db :refer [id-literal]]
|
||||||
[datomic.function :refer [construct]])
|
[datomic.function :refer [construct]]
|
||||||
|
[auto-ap.logging :as alog])
|
||||||
(:import
|
(:import
|
||||||
(java.util UUID)))
|
(java.util UUID)))
|
||||||
|
|
||||||
@@ -579,8 +580,6 @@
|
|||||||
(defn add-sorter-fields [q sort-map args]
|
(defn add-sorter-fields [q sort-map args]
|
||||||
(reduce
|
(reduce
|
||||||
(fn [q {:keys [sort-key] :as z}]
|
(fn [q {:keys [sort-key] :as z}]
|
||||||
(prn z)
|
|
||||||
(println (class sort-key))
|
|
||||||
(merge-query q
|
(merge-query q
|
||||||
{:query {:find [(symbol (str "?sort-" sort-key))]
|
{:query {:find [(symbol (str "?sort-" sort-key))]
|
||||||
:where (sort-map
|
:where (sort-map
|
||||||
@@ -896,3 +895,22 @@
|
|||||||
(defn query2 [query]
|
(defn query2 [query]
|
||||||
(apply dc/q (:query query) (:args query)))
|
(apply dc/q (:query query) (:args query)))
|
||||||
|
|
||||||
|
(defn observable-q [query]
|
||||||
|
nil)
|
||||||
|
|
||||||
|
(defn observable-query [query]
|
||||||
|
(mu/with-context {:query (:query query)
|
||||||
|
:args (:args query)
|
||||||
|
:query-stats true
|
||||||
|
:io-context ::hello}
|
||||||
|
(mu/trace ::query
|
||||||
|
[]
|
||||||
|
(let [query-results (dc/query {:query (:query query)
|
||||||
|
:args (:args query)
|
||||||
|
:query-stats true
|
||||||
|
:io-context ::hello})]
|
||||||
|
(alog/info ::query-stats
|
||||||
|
:io-stats (:io-stats query-results)
|
||||||
|
:query-stats (:query-stats query-results))
|
||||||
|
(:ret query-results)))))
|
||||||
|
|
||||||
|
|||||||
@@ -6,13 +6,13 @@
|
|||||||
apply-sort-3
|
apply-sort-3
|
||||||
conn
|
conn
|
||||||
merge-query
|
merge-query
|
||||||
pull-many
|
observable-query
|
||||||
query2]]
|
pull-many]]
|
||||||
[auto-ap.graphql.utils :refer [limited-clients]]
|
[auto-ap.graphql.utils :refer [extract-client-ids]]
|
||||||
[clj-time.coerce :as c]
|
[clj-time.coerce :as c]
|
||||||
[clojure.set :refer [rename-keys]]
|
[clojure.set :refer [rename-keys]]
|
||||||
[clojure.tools.logging :as log]
|
[datomic.api :as dc]
|
||||||
[datomic.api :as dc]))
|
[clj-time.coerce :as coerce]))
|
||||||
|
|
||||||
(defn <-datomic [result]
|
(defn <-datomic [result]
|
||||||
(-> result
|
(-> result
|
||||||
@@ -38,18 +38,25 @@
|
|||||||
(defn raw-graphql-ids
|
(defn raw-graphql-ids
|
||||||
([args] (raw-graphql-ids (dc/db conn) args))
|
([args] (raw-graphql-ids (dc/db conn) args))
|
||||||
([db args]
|
([db args]
|
||||||
(let [check-number-like (try (Long/parseLong (:check-number-like args)) (catch Exception _ nil))
|
(let [valid-clients (extract-client-ids (:clients args)
|
||||||
|
(:client-id args)
|
||||||
|
(when (:client-code args)
|
||||||
|
[:client/code (:client-code args)]))
|
||||||
|
check-number-like (try (Long/parseLong (:check-number-like args)) (catch Exception _ nil))
|
||||||
query (if (:exact-match-id args)
|
query (if (:exact-match-id args)
|
||||||
{:query {:find '[?e]
|
{:query {:find '[?e]
|
||||||
:in '[$ ?e [?c ...]]
|
:in '[$ ?e [?c ...]]
|
||||||
:where '[[?e :payment/client ?c]]}
|
:where '[[?e :payment/client ?c]]}
|
||||||
:args [db
|
:args [db
|
||||||
(:exact-match-id args)
|
(:exact-match-id args)
|
||||||
(map :db/id (:clients args))]}
|
valid-clients]}
|
||||||
(cond-> {:query {:find []
|
(cond-> {:query {:find []
|
||||||
:in ['$]
|
:in '[$ [?clients ?start ?end]]
|
||||||
:where []}
|
:where '[[(iol-ion.query/scan-payments $ ?clients ?start ?end) [[?e _ ?sort-default] ...]]]}
|
||||||
:args [db]}
|
:args [db
|
||||||
|
[valid-clients
|
||||||
|
(some-> (:start (:date-range args)) coerce/to-date)
|
||||||
|
(some-> (:end (:date-range args)) coerce/to-date)]]}
|
||||||
(:sort args) (add-sorter-fields {"client" ['[?e :payment/client ?c]
|
(:sort args) (add-sorter-fields {"client" ['[?e :payment/client ?c]
|
||||||
'[?c :client/name ?sort-client]]
|
'[?c :client/name ?sort-client]]
|
||||||
"vendor" ['[?e :payment/vendor ?v]
|
"vendor" ['[?e :payment/vendor ?v]
|
||||||
@@ -66,23 +73,6 @@
|
|||||||
:where []}
|
:where []}
|
||||||
:args [(:exact-match-id args)]})
|
:args [(:exact-match-id args)]})
|
||||||
|
|
||||||
true
|
|
||||||
(merge-query {:query {:in ['[?xx ...]]
|
|
||||||
:where ['[?e :payment/client ?xx]]}
|
|
||||||
:args [(map :db/id (:clients args))]})
|
|
||||||
|
|
||||||
|
|
||||||
(:client-id args)
|
|
||||||
(merge-query {:query {:in ['?client-id]
|
|
||||||
:where ['[?e :payment/client ?client-id]]}
|
|
||||||
:args [(:client-id args)]})
|
|
||||||
(:client-code args)
|
|
||||||
(merge-query {:query {:in ['?client-code]
|
|
||||||
:where ['[?e :payment/client ?client-id]
|
|
||||||
'[?client-id :client/code ?client-code]]}
|
|
||||||
:args [(:client-code args)]})
|
|
||||||
|
|
||||||
|
|
||||||
(:vendor-id args)
|
(:vendor-id args)
|
||||||
(merge-query {:query {:in ['?vendor-id]
|
(merge-query {:query {:in ['?vendor-id]
|
||||||
:where ['[?e :payment/vendor ?vendor-id]]}
|
:where ['[?e :payment/vendor ?vendor-id]]}
|
||||||
@@ -134,18 +124,6 @@
|
|||||||
:where ['[?e :payment/status ?status]]}
|
:where ['[?e :payment/status ?status]]}
|
||||||
:args [(:status args)]})
|
:args [(:status args)]})
|
||||||
|
|
||||||
(:start (:date-range args))
|
|
||||||
(merge-query {:query {:in '[?start-date]
|
|
||||||
:where ['[?e :payment/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 :payment/date ?date]
|
|
||||||
'[(<= ?date ?end-date)]]}
|
|
||||||
:args [(c/to-date (:end (:date-range args)))]})
|
|
||||||
|
|
||||||
(:payment-type args)
|
(:payment-type args)
|
||||||
(merge-query {:query {:in '[?payment-type]
|
(merge-query {:query {:in '[?payment-type]
|
||||||
:where ['[?e :payment/type ?payment-type]]}
|
:where ['[?e :payment/type ?payment-type]]}
|
||||||
@@ -157,12 +135,10 @@
|
|||||||
:args [check-number-like]})
|
:args [check-number-like]})
|
||||||
|
|
||||||
true
|
true
|
||||||
(merge-query {:query {:find ['?sort-default '?e]
|
(merge-query {:query {:find ['?sort-default '?e]}})))]
|
||||||
:where ['[?e :payment/date ?sort-default]]}})))]
|
|
||||||
|
|
||||||
|
|
||||||
(log/info query)
|
(cond->> (observable-query query)
|
||||||
(cond->> (query2 query)
|
|
||||||
true (apply-sort-3 (assoc args :default-asc? false))
|
true (apply-sort-3 (assoc args :default-asc? false))
|
||||||
true (apply-pagination args)))))
|
true (apply-pagination args)))))
|
||||||
|
|
||||||
|
|||||||
@@ -4,13 +4,14 @@
|
|||||||
:refer [add-sorter-fields
|
:refer [add-sorter-fields
|
||||||
apply-pagination
|
apply-pagination
|
||||||
query2
|
query2
|
||||||
|
observable-query
|
||||||
apply-sort-3
|
apply-sort-3
|
||||||
conn
|
conn
|
||||||
merge-query
|
merge-query
|
||||||
pull-many]]
|
pull-many]]
|
||||||
[auto-ap.datomic.accounts :as d-accounts]
|
[auto-ap.datomic.accounts :as d-accounts]
|
||||||
[auto-ap.datomic.vendors :as d-vendors]
|
[auto-ap.datomic.vendors :as d-vendors]
|
||||||
[auto-ap.graphql.utils :refer [limited-clients]]
|
[auto-ap.graphql.utils :refer [limited-clients extract-client-ids]]
|
||||||
[auto-ap.time-utils :refer [next-dom]]
|
[auto-ap.time-utils :refer [next-dom]]
|
||||||
[clj-time.coerce :as coerce]
|
[clj-time.coerce :as coerce]
|
||||||
[clj-time.core :as time]
|
[clj-time.core :as time]
|
||||||
@@ -48,18 +49,27 @@
|
|||||||
([args]
|
([args]
|
||||||
(raw-graphql-ids (dc/db conn) args))
|
(raw-graphql-ids (dc/db conn) args))
|
||||||
([db args]
|
([db args]
|
||||||
(let [query
|
(let [valid-clients (extract-client-ids (:clients args)
|
||||||
|
(:client-id args)
|
||||||
|
(when (:client-code args)
|
||||||
|
[:client/code (:client-code args)]))
|
||||||
|
query
|
||||||
(if (:exact-match-id args)
|
(if (:exact-match-id args)
|
||||||
{:query {:find '[?e]
|
{:query {:find '[?e]
|
||||||
:in '[$ ?e [?c ...]]
|
:in '[$ ?e [?c ...]]
|
||||||
:where '[[?e :invoice/client ?c]]}
|
:where '[[?e :invoice/client ?c]]}
|
||||||
:args [db
|
:args [db
|
||||||
(:exact-match-id args)
|
(:exact-match-id args)
|
||||||
(map :db/id (:clients args))]}
|
valid-clients]}
|
||||||
(cond-> {:query {:find []
|
(cond-> {:query {:find []
|
||||||
:in ['$]
|
:in '[$ [?clients ?start ?end]]
|
||||||
:where []}
|
:where '[
|
||||||
:args [db]}
|
[(iol-ion.query/scan-invoices $ ?clients ?start ?end) [[?e _ ?sort-default] ...]]
|
||||||
|
]}
|
||||||
|
:args [db
|
||||||
|
[valid-clients
|
||||||
|
(some-> (:start (:date-range args)) coerce/to-date)
|
||||||
|
(some-> (:end (:date-range args)) coerce/to-date)]]}
|
||||||
|
|
||||||
|
|
||||||
(:client-id args)
|
(:client-id args)
|
||||||
@@ -81,15 +91,9 @@
|
|||||||
:args [ (cond-> (:original-id args)
|
:args [ (cond-> (:original-id args)
|
||||||
(string? (:original-id args)) Long/parseLong )]})
|
(string? (:original-id args)) Long/parseLong )]})
|
||||||
|
|
||||||
(:start (:date-range args)) (merge-query {:query {:in '[?start-date]
|
|
||||||
:where ['[?e :invoice/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 :invoice/date ?date]
|
|
||||||
'[(<= ?date ?end-date)]]}
|
|
||||||
:args [(coerce/to-date (:end (:date-range args)))]})
|
|
||||||
|
|
||||||
(:start (:due-range args)) (merge-query {:query {:in '[?start-due]
|
(:start (:due-range args)) (merge-query {:query {:in '[?start-due]
|
||||||
:where ['[?e :invoice/due ?due]
|
:where ['[?e :invoice/due ?due]
|
||||||
@@ -100,10 +104,7 @@
|
|||||||
:where ['[?e :invoice/due ?due]
|
:where ['[?e :invoice/due ?due]
|
||||||
'[(<= ?due ?end-due)]]}
|
'[(<= ?due ?end-due)]]}
|
||||||
:args [(coerce/to-date (:end (:due-range args)))]})
|
:args [(coerce/to-date (:end (:due-range args)))]})
|
||||||
true
|
|
||||||
(merge-query {:query {:in ['[?xx ...]]
|
|
||||||
:where ['[?e :invoice/client ?xx]]}
|
|
||||||
:args [ (map :db/id (:clients args))]})
|
|
||||||
|
|
||||||
(:import-status args)
|
(:import-status args)
|
||||||
(merge-query {:query {:in ['?import-status]
|
(merge-query {:query {:in ['?import-status]
|
||||||
@@ -175,10 +176,8 @@
|
|||||||
"outstanding-balance" ['[?e :invoice/outstanding-balance ?sort-outstanding-balance]]}
|
"outstanding-balance" ['[?e :invoice/outstanding-balance ?sort-outstanding-balance]]}
|
||||||
args)
|
args)
|
||||||
true
|
true
|
||||||
(merge-query {:query {:find ['?sort-default '?e ]
|
(merge-query {:query {:find ['?sort-default '?e ]}}) ))]
|
||||||
:where ['[?e :invoice/client]
|
(->> (observable-query query)
|
||||||
'[?e :invoice/date ?sort-default]]}}) ))]
|
|
||||||
(->> (query2 query)
|
|
||||||
(apply-sort-3 args)
|
(apply-sort-3 args)
|
||||||
(apply-pagination args)))))
|
(apply-pagination args)))))
|
||||||
|
|
||||||
|
|||||||
@@ -6,31 +6,33 @@
|
|||||||
apply-sort-3
|
apply-sort-3
|
||||||
conn
|
conn
|
||||||
merge-query
|
merge-query
|
||||||
pull-many
|
observable-query
|
||||||
query2]]
|
pull-many]]
|
||||||
[auto-ap.datomic.accounts :as d-accounts]
|
[auto-ap.datomic.accounts :as d-accounts]
|
||||||
[auto-ap.graphql.utils :refer [limited-clients]]
|
[auto-ap.graphql.utils :refer [extract-client-ids]]
|
||||||
[clj-time.coerce :as c]
|
[clj-time.coerce :as coerce]
|
||||||
[datomic.api :as dc]))
|
[datomic.api :as dc]))
|
||||||
|
|
||||||
(defn raw-graphql-ids [db args]
|
(defn raw-graphql-ids [db args]
|
||||||
(let [query
|
(let [valid-clients (extract-client-ids (:clients args)
|
||||||
|
(:client-id args)
|
||||||
|
(when (:client-code args)
|
||||||
|
[:client/code (:client-code args)]))
|
||||||
|
query
|
||||||
(if (:exact-match-id args)
|
(if (:exact-match-id args)
|
||||||
{:query {:find '[?e]
|
{:query {:find '[?e]
|
||||||
:in '[$ ?e [?c ...]]
|
:in '[$ ?e [?c ...]]
|
||||||
:where '[[?e :journal-entry/client ?c]]}
|
:where '[[?e :journal-entry/client ?c]]}
|
||||||
:args [db
|
:args [db
|
||||||
(:exact-match-id args)
|
(:exact-match-id args)
|
||||||
(map :db/id (:clients args))]}
|
valid-clients]}
|
||||||
(cond-> {:query {:find []
|
(cond-> {:query {:find []
|
||||||
:in ['$ ]
|
:in ['$ '[?clients ?start ?end]]
|
||||||
:where []}
|
:where '[[(iol-ion.query/scan-ledger $ ?clients ?start ?end) [[?e _ ?sort-default] ...]]]}
|
||||||
:args [db]}
|
:args [db
|
||||||
|
[valid-clients
|
||||||
true
|
(some-> (:start (:date-range args)) coerce/to-date)
|
||||||
(merge-query {:query {:in ['[?xx ...]]
|
(some-> (:end (:date-range args)) coerce/to-date)]]}
|
||||||
:where ['[?e :journal-entry/client ?xx]]}
|
|
||||||
:args [(set (map :db/id (:clients args)))]})
|
|
||||||
|
|
||||||
(:only-external args)
|
(:only-external args)
|
||||||
(merge-query {:query {:where ['(not [?e :journal-entry/original-entity ])]}})
|
(merge-query {:query {:where ['(not [?e :journal-entry/original-entity ])]}})
|
||||||
@@ -51,23 +53,6 @@
|
|||||||
:where ['[?e :journal-entry/vendor ?vendor-id]]}
|
:where ['[?e :journal-entry/vendor ?vendor-id]]}
|
||||||
:args [(:vendor-id args)]})
|
:args [(:vendor-id args)]})
|
||||||
|
|
||||||
(:client-code args)
|
|
||||||
(merge-query {:query {:in ['?client-code]
|
|
||||||
:where ['[?e :journal-entry/client ?client-id]
|
|
||||||
'[?client-id :client/code ?client-code]]}
|
|
||||||
:args [(:client-code args)]})
|
|
||||||
|
|
||||||
(:start (:date-range args))
|
|
||||||
(merge-query {:query {:in ['?start-date]
|
|
||||||
:where ['[?e :journal-entry/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 :journal-entry/date ?date]
|
|
||||||
'[(<= ?date ?end-date)]]}
|
|
||||||
:args [(c/to-date (:end (:date-range args)))]})
|
|
||||||
|
|
||||||
(or (seq (:numeric-code args))
|
(or (seq (:numeric-code args))
|
||||||
(:bank-account-id args)
|
(:bank-account-id args)
|
||||||
@@ -130,8 +115,8 @@
|
|||||||
args)
|
args)
|
||||||
|
|
||||||
true
|
true
|
||||||
(merge-query {:query {:find ['?sort-default '?e] :where ['[?e :journal-entry/date ?sort-default]]}})))]
|
(merge-query {:query {:find ['?sort-default '?e]}})))]
|
||||||
(->> (query2 query)
|
(->> (observable-query query)
|
||||||
(apply-sort-3 (update args :sort conj {:sort-key "default-2" :asc true}))
|
(apply-sort-3 (update args :sort conj {:sort-key "default-2" :asc true}))
|
||||||
(apply-pagination args))))
|
(apply-pagination args))))
|
||||||
|
|
||||||
@@ -144,7 +129,7 @@
|
|||||||
{:account-client-override/client [:db/id]}]}
|
{:account-client-override/client [:db/id]}]}
|
||||||
{:bank-account/type [*]}]}]}]
|
{:bank-account/type [*]}]}]}]
|
||||||
ids)
|
ids)
|
||||||
(map #(update % :journal-entry/date c/from-date))
|
(map #(update % :journal-entry/date coerce/from-date))
|
||||||
(map (fn [je]
|
(map (fn [je]
|
||||||
(update je :journal-entry/line-items
|
(update je :journal-entry/line-items
|
||||||
(fn [jels]
|
(fn [jels]
|
||||||
|
|||||||
@@ -6,13 +6,12 @@
|
|||||||
apply-sort-3
|
apply-sort-3
|
||||||
conn
|
conn
|
||||||
merge-query
|
merge-query
|
||||||
pull-many
|
observable-query
|
||||||
query2]]
|
pull-many]]
|
||||||
[auto-ap.datomic.accounts :as d-accounts]
|
[auto-ap.datomic.accounts :as d-accounts]
|
||||||
[auto-ap.graphql.utils :refer [limited-clients]]
|
[auto-ap.graphql.utils :refer [extract-client-ids]]
|
||||||
[clj-time.coerce :as coerce]
|
[clj-time.coerce :as coerce]
|
||||||
[clojure.string :as str]
|
[clojure.string :as str]
|
||||||
[clojure.tools.logging :as log]
|
|
||||||
[datomic.api :as dc]))
|
[datomic.api :as dc]))
|
||||||
|
|
||||||
(defn potential-duplicate-ids [db args]
|
(defn potential-duplicate-ids [db args]
|
||||||
@@ -41,7 +40,11 @@
|
|||||||
(defn raw-graphql-ids
|
(defn raw-graphql-ids
|
||||||
([args] (raw-graphql-ids (dc/db conn) args))
|
([args] (raw-graphql-ids (dc/db conn) args))
|
||||||
([db args]
|
([db args]
|
||||||
(let [potential-duplicates (potential-duplicate-ids db args)
|
(let [valid-clients (extract-client-ids (:clients args)
|
||||||
|
(:client-id args)
|
||||||
|
(when (:client-code args)
|
||||||
|
[:client/code (:client-code args)]))
|
||||||
|
potential-duplicates (potential-duplicate-ids db args)
|
||||||
query
|
query
|
||||||
(if (:exact-match-id args)
|
(if (:exact-match-id args)
|
||||||
(cond-> {:query {:find '[?e]
|
(cond-> {:query {:find '[?e]
|
||||||
@@ -49,21 +52,19 @@
|
|||||||
:where '[[?e :transaction/client ?c]]}
|
:where '[[?e :transaction/client ?c]]}
|
||||||
:args [db
|
:args [db
|
||||||
(:exact-match-id args)
|
(:exact-match-id args)
|
||||||
(map :db/id (:clients args))]})
|
valid-clients]})
|
||||||
(cond-> {:query {:find []
|
(cond-> {:query {:find []
|
||||||
:in ['$ ]
|
:in '[$ [?clients ?start ?end]]
|
||||||
:where []}
|
:where '[[(iol-ion.query/scan-transactions $ ?clients ?start ?end) [[?e _ ?sort-default] ...]]]}
|
||||||
:args [db]}
|
:args [db
|
||||||
|
[valid-clients
|
||||||
|
(some-> (:start (:date-range args)) coerce/to-date)
|
||||||
|
(some-> (:end (:date-range args)) coerce/to-date)]]}
|
||||||
|
|
||||||
(:potential-duplicates args)
|
(:potential-duplicates args)
|
||||||
(merge-query {:query {:in '[[?e ...]]}
|
(merge-query {:query {:in '[[?e ...]]}
|
||||||
:args [potential-duplicates]})
|
:args [potential-duplicates]})
|
||||||
|
|
||||||
true
|
|
||||||
(merge-query {:query {:in ['[?xx ...]]
|
|
||||||
:where ['[?e :transaction/client ?xx]]}
|
|
||||||
:args [(set (map :db/id (:clients args)))]})
|
|
||||||
|
|
||||||
(:bank-account-id args)
|
(:bank-account-id args)
|
||||||
(merge-query {:query {:in ['?bank-account-id]
|
(merge-query {:query {:in ['?bank-account-id]
|
||||||
:where ['[?e :transaction/bank-account ?bank-account-id]]}
|
:where ['[?e :transaction/bank-account ?bank-account-id]]}
|
||||||
@@ -80,11 +81,6 @@
|
|||||||
'[?accounts :transaction-account/account ?account-id]]}
|
'[?accounts :transaction-account/account ?account-id]]}
|
||||||
:args [(:account-id args)]})
|
:args [(:account-id args)]})
|
||||||
|
|
||||||
(:client-id args)
|
|
||||||
(merge-query {:query {:in ['?client-id]
|
|
||||||
:where ['[?e :transaction/client ?client-id]]}
|
|
||||||
:args [(:client-id args)]})
|
|
||||||
|
|
||||||
(:vendor-id args)
|
(:vendor-id args)
|
||||||
(merge-query {:query {:in ['?vendor-id]
|
(merge-query {:query {:in ['?vendor-id]
|
||||||
:where ['[?e :transaction/vendor ?vendor-id]]}
|
:where ['[?e :transaction/vendor ?vendor-id]]}
|
||||||
@@ -103,29 +99,11 @@
|
|||||||
'[(<= ?a ?amount-lte)]]}
|
'[(<= ?a ?amount-lte)]]}
|
||||||
:args [(:amount-lte args)]})
|
:args [(:amount-lte 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)
|
(:approval-status args)
|
||||||
(merge-query {:query {:in ['?approval-status]
|
(merge-query {:query {:in ['?approval-status]
|
||||||
:where ['[?e :transaction/approval-status ?approval-status]]}
|
:where ['[?e :transaction/approval-status ?approval-status]]}
|
||||||
:args [(:approval-status args)]})
|
: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)
|
(:original-id args)
|
||||||
(merge-query {:query {:in ['?original-id]
|
(merge-query {:query {:in ['?original-id]
|
||||||
:where ['[?e :transaction/client ?c]
|
:where ['[?e :transaction/client ?c]
|
||||||
@@ -174,10 +152,8 @@
|
|||||||
true
|
true
|
||||||
(merge-query {:query {:find ['?sort-default '?e]
|
(merge-query {:query {:find ['?sort-default '?e]
|
||||||
:where ['[?e :transaction/id]
|
:where ['[?e :transaction/id]
|
||||||
'[?e :transaction/date ?sort-default]
|
|
||||||
'(not [?e :transaction/approval-status :transaction-approval-status/suppressed])]}})))]
|
'(not [?e :transaction/approval-status :transaction-approval-status/suppressed])]}})))]
|
||||||
(log/info "query is" query)
|
(cond->> (observable-query query)
|
||||||
(cond->> (query2 query)
|
|
||||||
true (apply-sort-3 (assoc args :default-asc? false))
|
true (apply-sort-3 (assoc args :default-asc? false))
|
||||||
true (apply-pagination args)))))
|
true (apply-pagination args)))))
|
||||||
|
|
||||||
|
|||||||
@@ -36,7 +36,8 @@
|
|||||||
[com.walmartlabs.lacinia.schema :as schema]
|
[com.walmartlabs.lacinia.schema :as schema]
|
||||||
[datomic.api :as dc]
|
[datomic.api :as dc]
|
||||||
[unilog.context :as lc]
|
[unilog.context :as lc]
|
||||||
[yang.time :refer [time-it]])
|
[yang.time :refer [time-it]]
|
||||||
|
[auto-ap.routes.auth :as auth])
|
||||||
(:import
|
(:import
|
||||||
(clojure.lang IPersistentMap)))
|
(clojure.lang IPersistentMap)))
|
||||||
|
|
||||||
@@ -243,7 +244,8 @@
|
|||||||
:profile_image_url {:type 'String}
|
:profile_image_url {:type 'String}
|
||||||
:email {:type 'String}
|
:email {:type 'String}
|
||||||
:role {:type :role}
|
:role {:type :role}
|
||||||
:clients {:type '(list :client)}}}
|
:clients {:type '(list :client)}
|
||||||
|
:impersonate_jwt {:type 'String}}}
|
||||||
|
|
||||||
:csv
|
:csv
|
||||||
{:fields {:csv_content_b64 {:type 'String}}}
|
{:fields {:csv_content_b64 {:type 'String}}}
|
||||||
@@ -622,7 +624,10 @@
|
|||||||
(defn get-user [context args _]
|
(defn get-user [context args _]
|
||||||
(assert-admin (:id context))
|
(assert-admin (:id context))
|
||||||
|
|
||||||
(let [users (d-users/get-graphql args)]
|
(let [users (->> (d-users/get-graphql args)
|
||||||
|
(map (fn [u]
|
||||||
|
(assoc u :impersonate_jwt
|
||||||
|
(auth/user->jwt u "FAKE_TOKEN")))))]
|
||||||
(->graphql users)))
|
(->graphql users)))
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -53,7 +53,8 @@
|
|||||||
|
|
||||||
(defn get-transaction-page [context args _]
|
(defn get-transaction-page [context args _]
|
||||||
(let [args (assoc (:filters args)
|
(let [args (assoc (:filters args)
|
||||||
:clients (:clients context))
|
:clients (:clients context)
|
||||||
|
:id (:id context))
|
||||||
_ (assert-filtered-enough args)
|
_ (assert-filtered-enough args)
|
||||||
[transactions transactions-count] (d-transactions/get-graphql (update (<-graphql args) :approval-status enum->keyword "transaction-approval-status"))
|
[transactions transactions-count] (d-transactions/get-graphql (update (<-graphql args) :approval-status enum->keyword "transaction-approval-status"))
|
||||||
transactions (map ->graphql (map approval-status->graphql transactions))]
|
transactions (map ->graphql (map approval-status->graphql transactions))]
|
||||||
|
|||||||
@@ -5,10 +5,12 @@
|
|||||||
[auto-ap.time :as atime]
|
[auto-ap.time :as atime]
|
||||||
[buddy.auth :refer [throw-unauthorized]]
|
[buddy.auth :refer [throw-unauthorized]]
|
||||||
[datomic.api :as dc]
|
[datomic.api :as dc]
|
||||||
|
[iol-ion.query :refer [entid]]
|
||||||
[clojure.walk :as walk]
|
[clojure.walk :as walk]
|
||||||
[com.walmartlabs.lacinia.util :refer [attach-resolvers]]
|
[com.walmartlabs.lacinia.util :refer [attach-resolvers]]
|
||||||
[clojure.tools.logging :as log]
|
[clojure.tools.logging :as log]
|
||||||
[com.brunobonacci.mulog :as mu]))
|
[com.brunobonacci.mulog :as mu]
|
||||||
|
[clojure.set :as set]))
|
||||||
|
|
||||||
|
|
||||||
(defn snake->kebab [s]
|
(defn snake->kebab [s]
|
||||||
@@ -163,6 +165,29 @@
|
|||||||
resolver-key (trace-query resolver-key resolver-fn))
|
resolver-key (trace-query resolver-key resolver-fn))
|
||||||
)
|
)
|
||||||
{}
|
{}
|
||||||
m))
|
m)))
|
||||||
|
|
||||||
)
|
(defn extract-client-ids [user-clients & possible-clients]
|
||||||
|
(let [coerce-client-ids (fn coerce-client-ids [x]
|
||||||
|
(cond (and (map? x)
|
||||||
|
(:db/id x))
|
||||||
|
[(:db/id x)]
|
||||||
|
|
||||||
|
(nat-int? x)
|
||||||
|
[x]
|
||||||
|
|
||||||
|
(and (vector? x)
|
||||||
|
(= :client/code (first x)))
|
||||||
|
[(entid (dc/db conn) x)]
|
||||||
|
|
||||||
|
|
||||||
|
(sequential? x)
|
||||||
|
(map x coerce-client-ids)
|
||||||
|
|
||||||
|
:else
|
||||||
|
[]))
|
||||||
|
user-client-ids (set (mapcat coerce-client-ids user-clients))
|
||||||
|
extra-client-ids (set (mapcat coerce-client-ids possible-clients))]
|
||||||
|
(if (seq extra-client-ids)
|
||||||
|
(set/intersection user-client-ids extra-client-ids)
|
||||||
|
user-client-ids)))
|
||||||
|
|||||||
@@ -179,7 +179,8 @@
|
|||||||
[handler]
|
[handler]
|
||||||
(fn [request]
|
(fn [request]
|
||||||
(let [x-clients (-> request :session :client-selection)
|
(let [x-clients (-> request :session :client-selection)
|
||||||
identity (-> request :session :identity)
|
identity (or (-> request :identity)
|
||||||
|
(-> request :session :identity))
|
||||||
ideal-ids (set (cond
|
ideal-ids (set (cond
|
||||||
(or (= :all x-clients)
|
(or (= :all x-clients)
|
||||||
(nil? x-clients))
|
(nil? x-clients))
|
||||||
@@ -235,6 +236,26 @@
|
|||||||
(into new-session)
|
(into new-session)
|
||||||
(assoc :client-selection x-clients))))))))
|
(assoc :client-selection x-clients))))))))
|
||||||
|
|
||||||
|
(defn wrap-gunzip-jwt
|
||||||
|
[handler]
|
||||||
|
(fn [{:keys [session] :as request}]
|
||||||
|
(let [request (if-let [gz-clients (some-> request :identity :gz-clients)]
|
||||||
|
(try
|
||||||
|
(assoc-in request [:identity :user/clients]
|
||||||
|
(auth/gunzip gz-clients))
|
||||||
|
(catch Exception e
|
||||||
|
(alog/error :cant-gunzip-clients
|
||||||
|
:error e)
|
||||||
|
request))
|
||||||
|
request)]
|
||||||
|
(handler request))))
|
||||||
|
|
||||||
|
#_(defn wrap-pprint-session
|
||||||
|
[handler]
|
||||||
|
(fn [request]
|
||||||
|
(clojure.pprint/pprint (:session request))
|
||||||
|
(handler request)))
|
||||||
|
|
||||||
#_{:clj-kondo/ignore [:clojure-lsp/unused-public-var]}
|
#_{:clj-kondo/ignore [:clojure-lsp/unused-public-var]}
|
||||||
(def app
|
(def app
|
||||||
(-> route-handler
|
(-> route-handler
|
||||||
@@ -242,16 +263,19 @@
|
|||||||
(wrap-guess-route)
|
(wrap-guess-route)
|
||||||
(wrap-hydrate-clients)
|
(wrap-hydrate-clients)
|
||||||
(wrap-store-client-in-session)
|
(wrap-store-client-in-session)
|
||||||
|
(wrap-gunzip-jwt)
|
||||||
(wrap-authorization auth-backend)
|
(wrap-authorization auth-backend)
|
||||||
(wrap-authentication auth-backend
|
(wrap-authentication auth-backend
|
||||||
(session-backend {:authfn (fn [auth]
|
(session-backend {:authfn (fn [auth]
|
||||||
(dissoc auth :exp))}))
|
(dissoc auth :exp))}))
|
||||||
|
|
||||||
|
#_(wrap-pprint-session)
|
||||||
(wrap-idle-session-timeout)
|
(wrap-idle-session-timeout)
|
||||||
(wrap-session {:store (cookie-store
|
(wrap-session {:store (cookie-store
|
||||||
{:key
|
{:key
|
||||||
(byte-array
|
(byte-array
|
||||||
[42, 52, -31, 105, -126, -33, -118, -69, -82, -59, -15, -69, -38, 103, -102, -1])} )})
|
[42, 52, -31, 105, -126, -33, -118, -69, -82, -59, -15, -69, -38, 103, -102, -1])} )})
|
||||||
|
|
||||||
(wrap-reload)
|
(wrap-reload)
|
||||||
(wrap-params)
|
(wrap-params)
|
||||||
(mp/wrap-multipart-params)
|
(mp/wrap-multipart-params)
|
||||||
|
|||||||
@@ -6,7 +6,9 @@
|
|||||||
[clj-time.core :as time]
|
[clj-time.core :as time]
|
||||||
[clojure.tools.logging :as log]
|
[clojure.tools.logging :as log]
|
||||||
[config.core :refer [env]]
|
[config.core :refer [env]]
|
||||||
[com.brunobonacci.mulog :as mu]))
|
[com.brunobonacci.mulog :as mu]
|
||||||
|
[clojure.java.io :as io]
|
||||||
|
[clojure.edn :as edn]))
|
||||||
|
|
||||||
(def google-client-id "264081895820-0nndcfo3pbtqf30sro82vgq5r27h8736.apps.googleusercontent.com")
|
(def google-client-id "264081895820-0nndcfo3pbtqf30sro82vgq5r27h8736.apps.googleusercontent.com")
|
||||||
(def google-client-secret "OC-WemHurPXYpuIw5cT-B90g")
|
(def google-client-secret "OC-WemHurPXYpuIw5cT-B90g")
|
||||||
@@ -20,6 +22,50 @@
|
|||||||
(:jwt-secret env)
|
(:jwt-secret env)
|
||||||
{:alg :hs512}))
|
{:alg :hs512}))
|
||||||
|
|
||||||
|
(defn gzip [data]
|
||||||
|
(let [data (pr-str data)
|
||||||
|
raw (java.io.ByteArrayOutputStream.)]
|
||||||
|
(with-open [output (-> raw
|
||||||
|
(io/output-stream)
|
||||||
|
(java.util.zip.GZIPOutputStream.))]
|
||||||
|
(io/copy data output))
|
||||||
|
(.encodeToString (java.util.Base64/getEncoder) (.toByteArray raw))))
|
||||||
|
|
||||||
|
(defn gunzip [b64]
|
||||||
|
|
||||||
|
(let [raw-bytes (.decode (java.util.Base64/getDecoder) b64)
|
||||||
|
raw (java.io.ByteArrayInputStream. raw-bytes)
|
||||||
|
out (java.io.ByteArrayOutputStream.)]
|
||||||
|
(with-open [compressed (-> raw
|
||||||
|
(io/input-stream)
|
||||||
|
(java.util.zip.GZIPInputStream.))]
|
||||||
|
(io/copy compressed out))
|
||||||
|
|
||||||
|
(edn/read-string (.toString out))))
|
||||||
|
|
||||||
|
(defn user->jwt [user oauth-token]
|
||||||
|
(let [auth (cond-> {:user (:user/name user)
|
||||||
|
:exp (time/plus (time/now) (time/days 30))
|
||||||
|
:db/id (:db/id user)
|
||||||
|
:user/role (name (:user/role user))
|
||||||
|
:user/name (:user/name user)}
|
||||||
|
(= "admin" (name (:user/role user)))
|
||||||
|
(assoc :gz-clients (->> (:user/clients user)
|
||||||
|
(map (fn [c]
|
||||||
|
(select-keys c [:client/code :db/id :client/locations])))
|
||||||
|
|
||||||
|
gzip))
|
||||||
|
(not= "admin" (name (:user/role user)))
|
||||||
|
(assoc :user/clients
|
||||||
|
(->> (:user/clients user)
|
||||||
|
(map (fn [c]
|
||||||
|
(select-keys c [:client/code :db/id :client/locations]))))))]
|
||||||
|
|
||||||
|
(when (and user oauth-token)
|
||||||
|
(jwt/sign auth
|
||||||
|
(:jwt-secret env)
|
||||||
|
{:alg :hs512}))))
|
||||||
|
|
||||||
(defn oauth [{{:strs [code state]} :query-params {:strs [host]} :headers :as request}]
|
(defn oauth [{{:strs [code state]} :query-params {:strs [host]} :headers :as request}]
|
||||||
(try
|
(try
|
||||||
(let [auth (-> "https://accounts.google.com/o/oauth2/token"
|
(let [auth (-> "https://accounts.google.com/o/oauth2/token"
|
||||||
@@ -43,25 +89,15 @@
|
|||||||
:user/email (:email profile)
|
:user/email (:email profile)
|
||||||
:user/profile-image-url (:picture profile)
|
:user/profile-image-url (:picture profile)
|
||||||
:user/name (:name profile)})
|
:user/name (:name profile)})
|
||||||
auth {:user (:name profile)
|
|
||||||
:exp (time/plus (time/now) (time/days 30))
|
|
||||||
:db/id (:db/id user)
|
|
||||||
:user/clients (map (fn [c]
|
|
||||||
(select-keys c [:client/code :db/id :client/locations]))
|
|
||||||
(:user/clients user))
|
|
||||||
:user/role (name (:user/role user))
|
|
||||||
:user/name (:name profile)}
|
|
||||||
_ (mu/log ::logged-in-as
|
_ (mu/log ::logged-in-as
|
||||||
:auth auth)]
|
:auth auth)]
|
||||||
;; TODO - these namespaces are not being transmitted/deserialized properly
|
;; TODO - these namespaces are not being transmitted/deserialized properly
|
||||||
|
|
||||||
(if (and token user)
|
(if-let [jwt (user->jwt user token)]
|
||||||
(let [jwt (jwt/sign auth
|
|
||||||
(:jwt-secret env)
|
|
||||||
{:alg :hs512})]
|
|
||||||
{:status 301
|
{:status 301
|
||||||
:headers {"Location" (str (or (not-empty state) "/") "?jwt=" jwt)}
|
:headers {"Location" (str (or (not-empty state) "/") "?jwt=" jwt)}
|
||||||
:session {:identity (dissoc auth :exp)}})
|
:session {:identity (dissoc auth :exp)}}
|
||||||
{:status 401
|
{:status 401
|
||||||
:body "Couldn't authenticate"}))
|
:body "Couldn't authenticate"}))
|
||||||
(catch Exception e
|
(catch Exception e
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
[auto-ap.routes :as routes]
|
[auto-ap.routes :as routes]
|
||||||
[auto-ap.utils :refer [by]]
|
[auto-ap.utils :refer [by]]
|
||||||
[auto-ap.views.pages.data-page :as data-page]
|
[auto-ap.views.pages.data-page :as data-page]
|
||||||
[auto-ap.views.utils :refer [parse-jwt with-user]]
|
[auto-ap.views.utils :refer [parse-jwt with-user gunzip]]
|
||||||
[bidi.bidi :as bidi]
|
[bidi.bidi :as bidi]
|
||||||
[clojure.string :as str]
|
[clojure.string :as str]
|
||||||
[clojure.edn :as edn]
|
[clojure.edn :as edn]
|
||||||
@@ -12,10 +12,18 @@
|
|||||||
[re-frame.core :as re-frame]
|
[re-frame.core :as re-frame]
|
||||||
[auto-ap.ssr-routes :as ssr-routes]
|
[auto-ap.ssr-routes :as ssr-routes]
|
||||||
[cemerick.url :as url]
|
[cemerick.url :as url]
|
||||||
[auto-ap.subs :as subs]))
|
[auto-ap.subs :as subs]
|
||||||
|
[pako]))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
(defn jwt->data [token]
|
(defn jwt->data [token]
|
||||||
(js->clj (.parse js/JSON (b64/decodeString (second (str/split token #"\." ))))))
|
(let [raw (js->clj (.parse js/JSON (b64/decodeString (second (str/split token #"\." )))))
|
||||||
|
gz-clients (or (:gz-clients raw)
|
||||||
|
(get raw "gz-clients"))]
|
||||||
|
(cond-> raw
|
||||||
|
gz-clients (assoc "user/clients" (gunzip gz-clients)))))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
(defn client-query []
|
(defn client-query []
|
||||||
|
|||||||
@@ -56,6 +56,11 @@
|
|||||||
(when (= "admin" (:user/role @user))
|
(when (= "admin" (:user/role @user))
|
||||||
[:a {:class "navbar-item" :href (bidi/path-for routes/routes :admin)} "Administration"])
|
[:a {:class "navbar-item" :href (bidi/path-for routes/routes :admin)} "Administration"])
|
||||||
[:hr {:class "navbar-divider"}]
|
[:hr {:class "navbar-divider"}]
|
||||||
|
[:a.navbar-item {:on-click (fn []
|
||||||
|
(.removeItem js/localStorage "last-client-id" nil)
|
||||||
|
(.setItem js/localStorage "last-selected-clients" ":all")
|
||||||
|
(.reload (.-location js/document ) true))}
|
||||||
|
"Full Refresh"]
|
||||||
[:a.navbar-item {:on-click (fn [e] (.preventDefault e) (re-frame/dispatch [::events/logout]))} "Logout"]]]
|
[:a.navbar-item {:on-click (fn [e] (.preventDefault e) (re-frame/dispatch [::events/logout]))} "Logout"]]]
|
||||||
[:a.navbar-item {:href (login-url)} "Login"])))
|
[:a.navbar-item {:href (login-url)} "Login"])))
|
||||||
|
|
||||||
|
|||||||
@@ -39,6 +39,7 @@
|
|||||||
[:name
|
[:name
|
||||||
:profile_image_url
|
:profile_image_url
|
||||||
:email
|
:email
|
||||||
|
:impersonate_jwt
|
||||||
:id
|
:id
|
||||||
:role
|
:role
|
||||||
[:clients [:id :name]]]]]}
|
[:clients [:id :name]]]]]}
|
||||||
|
|||||||
@@ -32,7 +32,7 @@
|
|||||||
[grid/header-cell {} "Email"]
|
[grid/header-cell {} "Email"]
|
||||||
[grid/header-cell {} "Role"]
|
[grid/header-cell {} "Role"]
|
||||||
[grid/header-cell {} "Clients"]
|
[grid/header-cell {} "Clients"]
|
||||||
[grid/header-cell {:style {:width (action-cell-width 1)}}]]]
|
[grid/header-cell {:style {:width (action-cell-width 5)}}]]]
|
||||||
[grid/body
|
[grid/body
|
||||||
(for [{:keys [id name role clients] :as c} (:data page)]
|
(for [{:keys [id name role clients] :as c} (:data page)]
|
||||||
^{:key (str name "-" id)}
|
^{:key (str name "-" id)}
|
||||||
@@ -50,6 +50,14 @@
|
|||||||
[grid/cell {} role]
|
[grid/cell {} role]
|
||||||
[grid/cell {} (str/join ", " (map :name clients))]
|
[grid/cell {} (str/join ", " (map :name clients))]
|
||||||
[grid/cell {}
|
[grid/cell {}
|
||||||
|
[:a.button {:on-click (fn []
|
||||||
|
(.setItem js/localStorage "jwt" (:impersonate-jwt c))
|
||||||
|
(.removeItem js/localStorage "last-client-id" nil)
|
||||||
|
(.removeItem js/localStorage "last-selected-clients" nil)
|
||||||
|
(.reload (.-location js/document ) true))}
|
||||||
|
"Impersonate"]
|
||||||
|
|
||||||
|
|
||||||
[buttons/fa-icon {:event [::form/editing c]
|
[buttons/fa-icon {:event [::form/editing c]
|
||||||
:icon "fa-pencil"}]]])]]
|
:icon "fa-pencil"}]]])]]
|
||||||
]))
|
]))
|
||||||
|
|||||||
@@ -8,10 +8,14 @@
|
|||||||
[:div.column.is-8.is-offset-2.has-text-centered
|
[:div.column.is-8.is-offset-2.has-text-centered
|
||||||
|
|
||||||
[:div.box.slideInFromBelow
|
[:div.box.slideInFromBelow
|
||||||
[:img {:src "http://www.integreatconsult.com/wp-content/uploads/2016/11/logo.png"}]
|
[:img {:src "/img/logo.png"}]
|
||||||
[:div.notification.is-danger.is-light "An unexpected error has occured. "
|
[:div.notification.is-danger.is-light "An unexpected error has occured. "
|
||||||
[:a {:on-click #(.reload (.-location js/document )) } "Click here"]
|
[:div [:a {:on-click (fn []
|
||||||
" to try again."]]
|
(.removeItem js/localStorage "last-client-id" nil)
|
||||||
|
(.removeItem js/localStorage "last-selected-clients" nil)
|
||||||
|
(.reload (.-location js/document ) true)) } "Click here"]
|
||||||
|
" to try again."]
|
||||||
|
[:div "If the error continues, please try " [:a {:href "/login"} "logging in"] " again."]]]
|
||||||
[:p.has-text-gray
|
[:p.has-text-gray
|
||||||
"Copyright Integreat 2020"]]]]]]
|
"Copyright Integreat 2020"]]]]]]
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -11,7 +11,8 @@
|
|||||||
[react-transition-group :as react-transition-group]
|
[react-transition-group :as react-transition-group]
|
||||||
#_{:clj-kondo/ignore [:unused-namespace]}
|
#_{:clj-kondo/ignore [:unused-namespace]}
|
||||||
[react :as react]
|
[react :as react]
|
||||||
[reagent.core :as r])
|
[reagent.core :as r]
|
||||||
|
[pako])
|
||||||
(:import
|
(:import
|
||||||
(goog.i18n NumberFormat)
|
(goog.i18n NumberFormat)
|
||||||
(goog.i18n.NumberFormat Format)))
|
(goog.i18n.NumberFormat Format)))
|
||||||
@@ -297,13 +298,25 @@
|
|||||||
:else
|
:else
|
||||||
x))
|
x))
|
||||||
|
|
||||||
|
(defn gunzip [b64]
|
||||||
|
(let [raw-byte-array (->> b64
|
||||||
|
js/atob
|
||||||
|
(map (fn [z] (.charCodeAt z 0)))
|
||||||
|
clj->js
|
||||||
|
(js/Uint8Array.))]
|
||||||
|
(or (edn/read-string (pako/inflate raw-byte-array #js {"to" "string"}))
|
||||||
|
nil)))
|
||||||
|
|
||||||
(defn parse-jwt [jwt]
|
(defn parse-jwt [jwt]
|
||||||
(when-let [json (some-> jwt
|
(when-let [json (some-> jwt
|
||||||
(str/split #"\.")
|
(str/split #"\.")
|
||||||
second
|
second
|
||||||
base64/decodeString)]
|
base64/decodeString)]
|
||||||
(js->clj (.parse js/JSON json) :keywordize-keys true)))
|
(let [raw (js->clj (.parse js/JSON json) :keywordize-keys true)
|
||||||
|
gz-clients (or (:gz-clients raw)
|
||||||
|
(get raw "gz-clients"))]
|
||||||
|
(cond-> raw
|
||||||
|
gz-clients (assoc :user/clients (gunzip gz-clients))))))
|
||||||
|
|
||||||
(defn coerce-float [f]
|
(defn coerce-float [f]
|
||||||
(cond (str/blank? f)
|
(cond (str/blank? f)
|
||||||
|
|||||||
Reference in New Issue
Block a user