This commit is contained in:
2023-08-31 23:24:42 -07:00
parent 1d82ec29e0
commit 7d251c8398
40 changed files with 333 additions and 286 deletions

View File

@@ -177,7 +177,6 @@
payments))
(defn get-graphql [args]
(log/info (:id args))
(let [db (dc/db conn)
{ids-to-retrieve :ids matching-count :count} (raw-graphql-ids db args)]

View File

@@ -165,15 +165,7 @@
:else
nil)
matching-ids (cond
(and name-like-ids (limited-clients (:id args)))
(set/intersection name-like-ids (limited-clients (:id args)))
name-like-ids
name-like-ids
:else
nil)
matching-ids name-like-ids
valid-ids (if matching-ids
(set/intersection (set (map :db/id (:clients args)))
matching-ids)

View File

@@ -60,10 +60,7 @@
:where ['[?e :invoice/client]]}
:args [db]}
(seq (:clients args))
(merge-query {:query {:in ['[?xx ...]]
:where ['[?e :invoice/client ?xx]]}
:args [ (map :db/id (:clients args))]})
(:client-id args)
(merge-query {:query {:in ['?client-id]
:where ['[?e :invoice/client ?client-id]]}
@@ -102,6 +99,10 @@
:where ['[?e :invoice/due ?due]
'[(<= ?due ?end-due)]]}
:args [(coerce/to-date (:end (:due-range args)))]})
(seq (:clients args))
(merge-query {:query {:in ['[?xx ...]]
:where ['[?e :invoice/client ?xx]]}
:args [ (map :db/id (:clients args))]})
(:import-status args)
(merge-query {:query {:in ['?import-status]

View File

@@ -119,10 +119,6 @@
:where ['[?li :journal-entry-line/location ?location]]}
:args [(:locations args)]})
(limited-clients (:id args))
(merge-query {:query {:in ['[?xx ...]]
:where ['[?e :journal-entry/client ?xx]]}
:args [(set (map :db/id (limited-clients (:id args))))]})
(:sort args) (add-sorter-fields {"client" ['[?e :journal-entry/client ?c]
'[?c :client/name ?sort-client]]
"date" ['[?e :journal-entry/date ?sort-date]]

View File

@@ -26,10 +26,6 @@
:where ['[?e :report/client ?xx]]}
:args [(set (map :db/id (:clients args)))]})
(limited-clients (:id args))
(merge-query {:query {:in ['[?xx ...]]
:where ['[?e :report/client ?xx]]}
:args [(set (map :db/id (limited-clients (:id args))))]})
(:sort args) (add-sorter-fields {"client" ['[?e :report/client ?c]
'[?c :client/name ?sort-client]]
"created" ['[?e :report/created ?sort-created]]

View File

@@ -732,8 +732,7 @@
(def input-objects
{:invoice_payment_amount {:fields {:invoice_id {:type :id}
:amount {:type :money}}}
:payment_filters {:fields {:client_id {:type :id}
:vendor_id {:type :id}
:payment_filters {:fields {:vendor_id {:type :id}
:payment_type {:type :payment_type}
:status {:type :payment_status}
:exact_match_id {:type :id}

View File

@@ -255,7 +255,6 @@
(defn get-ids-matching-filters [args]
(let [ids (some-> args
:filters
(assoc :id (:id args))
(<-graphql)
(update :status enum->keyword "invoice-status")
(assoc :per-page Integer/MAX_VALUE)
@@ -278,7 +277,7 @@
(defn void-invoices [context args _]
(let [_ (assert-admin (:id context))
args (assoc args :id (:id context))
args (assoc args :clients (:clients context))
all-ids (all-ids-not-locked (get-ids-matching-filters args))
voidable-cash-payments (->> (dc/q '[:find ?p
:in $ [?i ...]
@@ -445,7 +444,7 @@
(when-not (:client_id args)
(throw (ex-info "Client is required"
{:validation-error "client is required"})))
(let [args (assoc args :id (:id context))
(let [args (assoc args :clients [{:db/id (:client_id args)}])
locations (pull-attr (dc/db conn)
:client/locations
(:client_id args))
@@ -602,7 +601,6 @@
:status {:type :invoice_status}
:unresolved {:type 'Boolean}
:scheduled_payments {:type 'Boolean}
:client_id {:type :id}
:vendor_id {:type :id}
:account_id {:type :id}
:amount_lte {:type :money}

View File

@@ -35,8 +35,14 @@
(defn get-ledger-page [context args _]
(let [args (assoc args :id (:id context))
_ (when (:client_id (:filters args))
(assert-can-see-client (:id context) (:client_id (:filters args))))
clients (or (and (:client_id (:filters args))
[{:db/id (:client_id (:filters args))}])
(:clients context))
[journal-entries journal-entries-count] (l/get-graphql (assoc (<-graphql (:filters args))
:clients (:clients context)))
:clients clients))
journal-entries (mapv
(fn [je]
@@ -49,7 +55,7 @@
(let [args (assoc args :id (:id context))
[journal-entries journal-entries-count] (l/get-graphql (assoc (<-graphql (:filters args))
:per-page Integer/MAX_VALUE
:id (:id context)))
:clients (:clients context)))
]
@@ -561,9 +567,9 @@
location (:client/locations c)
category (:categories input)
:let [category (<-graphql category)
all-journal-entries (->> (get-ledger-page context
{:filters {:client_id client-id
:location location
all-journal-entries (->> (get-ledger-page (assoc context
:clients [{:db/id client-id}])
{:filters {:location location
:date_range (:date_range input)
:from_numeric_code (l-reports/min-numeric-code category )
:to_numeric_code (l-reports/max-numeric-code category )

View File

@@ -9,7 +9,7 @@
[datomic.api :as dc]))
(defn get-report-page [context args _]
(let [args (assoc args :id (:id context))
(let [args (assoc args :clients (:clients context))
[reports reports-count] (r/get-graphql (assoc (<-graphql (:filters args))
:clients (:clients context)))]
(result->page reports reports-count :reports (:filters args)))
@@ -58,8 +58,7 @@
(def input-objects
{:report_filters
{:fields {:client_id {:type :id}
:start {:type 'Int}
{:fields {:start {:type 'Int}
:per_page {:type 'Int}
:sort {:type '(list :sort_item)}}}})

View File

@@ -41,7 +41,7 @@
(when-not (seq (->> filters
(filter (fn [[_ v]]
(not (nil? v))))
(filter (comp (complement #{:id :start :sort :client_id :bank_account_id :potential_duplicates :per_page})
(filter (comp (complement #{:id :start :sort :bank_account_id :potential_duplicates :per_page})
first))
(filter (fn [[k v]]
(if (= :date_range k)
@@ -141,8 +141,7 @@
(when-not (seq (:client_id args))
(throw (ex-info "Client is required"
{:validation-error "client is required"})))
;; TODO FIX THIS TO WORK WITH MULTIPLE
(let [args (assoc args :clients (:clients context))
(let [args (assoc args :clients [{:db/id [(:client_id args)]}])
locations (pull-attr (dc/db conn)
:client/locations
(:client_id args))
@@ -589,7 +588,6 @@
:resolve :mutation/bulk-change-transaction-status}
:bulk_code_transactions {:type :message
:args {:filters {:type :transaction_filters}
:client_id {:type :id}
:vendor {:type :id}
:approval_status {:type :transaction_approval_status}
:accounts {:type '(list :edit_percentage_account)}
@@ -630,8 +628,7 @@
:resolve :mutation/match-transaction-rules}})
(def input-objects
{:transaction_filters {:fields {:client_id {:type :id}
:exact_match_id {:type :id}
{:transaction_filters {:fields {:exact_match_id {:type :id}
:import_batch_id {:type :id}
:potential_duplicates {:type 'Boolean}
:vendor_id {:type :id}

View File

@@ -2,7 +2,9 @@
(:require
[amazonica.core :refer [defcredential]]
[auto-ap.client-routes :as client-routes]
[auto-ap.ssr-routes :as ssr-routes]
[auto-ap.datomic :refer [conn pull-many]]
[auto-ap.datomic.clients :as d-clients]
[auto-ap.graphql.utils :refer [assert-can-see-client limited-clients]]
[auto-ap.logging :as alog]
[auto-ap.routes.auth :as auth]
[auto-ap.routes.exports :as exports]
@@ -12,15 +14,21 @@
[auto-ap.routes.invoices :as invoices]
[auto-ap.routes.queries :as queries]
[auto-ap.routes.yodlee2 :as yodlee2]
[auto-ap.ssr-routes :as ssr-routes]
[auto-ap.ssr.core :as ssr]
[bidi.bidi :as bidi]
[bidi.ring :refer [->ResourcesMaybe make-handler]]
[buddy.auth.backends.session :refer [session-backend]]
[buddy.auth.backends.token :refer [jws-backend]]
[buddy.auth.middleware :refer [wrap-authentication wrap-authorization]]
[cemerick.url :as url]
[clj-time.coerce :as coerce]
[clj-time.core :as time]
[clojure.string :as str]
[clojure.edn :as edn]
[com.brunobonacci.mulog :as mu]
[config.core :refer [env]]
[datomic.api :as dc]
[ring.middleware.edn :refer [wrap-edn-params]]
[ring.middleware.multipart-params :as mp]
[ring.middleware.params :refer [wrap-params]]
@@ -29,9 +37,7 @@
[ring.middleware.session.cookie :refer [cookie-store]]
[ring.util.response :as response]
[unilog.context :as lc]
[clj-time.coerce :as coerce]
[clj-time.core :as time]
[cemerick.url :as url]))
[clojure.set :as set]))
(when (:aws-access-key-id env)
(defcredential (:aws-access-key-id env) (:aws-secret-access-key env) (:aws-region env)))
@@ -169,13 +175,67 @@
request (assoc request :hx-query-params query-params)]
(handler request))))
(defn wrap-hydrate-clients
[handler]
(fn [request]
(let [x-clients (-> request :session :client-selection)
identity (-> request :session :identity)
ideal-ids (set (cond
(or (= :all x-clients)
(nil? x-clients))
(->> (dc/q '[:find ?c
:where [?c :client/code]]
(dc/db conn))
(map first))
(= :mine x-clients)
(map :db/id (:user/clients identity))
(seq x-clients)
x-clients))
limited-clients (some->> (limited-clients identity)
(map :db/id )
set)
client-ids (if (set? limited-clients)
(set/intersection ideal-ids
limited-clients)
ideal-ids)
clients (pull-many (dc/db conn)
d-clients/full-read
client-ids)]
(lc/with-context {:clients (map :client/code clients)}
(handler (assoc request
:clients clients
:client (when (= 1 (count clients))
(first clients))))))))
(defn wrap-store-client-in-session
[handler]
(fn [{:keys [headers identity] :as request}]
(let [x-clients (edn/read-string (get headers "x-clients"))
_ (when-let [client-id (and x-clients
(sequential? x-clients)
(first x-clients))]
(assert-can-see-client identity client-id))
new-request (if x-clients
(assoc-in request [:session :client-selection] x-clients)
request)]
(cond-> (handler new-request)
x-clients (update :session
(fn [new-session]
(-> (:session request)
(into new-session)
(assoc :client-selection x-clients))))))))
#_{:clj-kondo/ignore [:clojure-lsp/unused-public-var]}
(def app
(-> route-handler
(wrap-hx-current-url-params)
(wrap-guess-route)
(wrap-authorization auth-backend
)
(wrap-hydrate-clients)
(wrap-store-client-in-session)
(wrap-authorization auth-backend)
(wrap-authentication auth-backend
(session-backend {:authfn (fn [auth]
(dissoc auth :exp))}))

View File

@@ -272,8 +272,6 @@
(.toByteArray output-stream)))
(defn make-journal-detail-report [args data]
(println args)
(let [data (<-graphql data)
args (<-graphql args)
clients (pull-many (dc/db conn) '[:client/code :client/name :db/id] (:client-ids args))

View File

@@ -193,7 +193,8 @@
(base-page
request
(com/page {:nav (com/admin-aside-nav)
:active-client (:client (:session request))
:client-selection (:client-selection (:session request))
:client (:client request)
:identity (:identity request)
:app-params {:hx-get (bidi/path-for ssr-routes/only-routes
:admin-ezcater-xls)

View File

@@ -12,37 +12,10 @@
[clojure.tools.logging :as log]
[datomic.api :as dc]))
(defn headers->clients [identity headers]
(let [x-clients (clojure.edn/read-string (get headers "x-clients"))
ideal-ids (set (cond
(or (= :all x-clients)
(nil? x-clients))
(->> (dc/q '[:find ?c
:where [?c :client/code]]
(dc/db conn))
(map first))
(= :mine x-clients)
(map :db/id (:user/clients identity))
(seq x-clients)
x-clients))
_ (println "X-CLIENSTT" x-clients)
_ (println "IDEAL" ideal-ids)
_ (println "LIMITS" (limited-clients identity))
limited-clients (some->> (limited-clients identity)
(map :db/id )
set)
client-ids (if (set? limited-clients)
(set/intersection ideal-ids
limited-clients)
ideal-ids)]
(pull-many (dc/db conn)
d-clients/full-read
client-ids)))
(defn handle-graphql [{:keys [request-method query-params] :as r}]
(defn handle-graphql [{:keys [request-method query-params clients] :as r}]
(when (= "none" (:user/role (:identity r)))
(throw-unauthorized))
@@ -54,7 +27,7 @@
{:status 200
:body (pr-str (ql/query (:identity r) (if (= request-method :get) (query-params "query") body) (assoc variables
:clients
(headers->clients (:identity r) (:headers r))) ))
clients) ))
:headers {"Content-Type" "application/edn"}})
(catch Throwable e
(log/info "here we are " (.getCause e))

View File

@@ -166,7 +166,8 @@
(some-> route-params (get :entity-id) Long/parseLong))]
(base-page request
(com/page {:nav (com/admin-aside-nav)
:active-client (:client (:session request))
:client-selection (:client-selection (:session request))
:client (:client request)
:identity (:identity request)
:app-params {:hx-get (bidi/path-for ssr-routes/only-routes
:admin-history)

View File

@@ -50,7 +50,8 @@
(base-page
request
(com/page {:nav (com/company-aside-nav)
:active-client (:client (:session request))
:client-selection (:client-selection (:session request))
:client (:client request)
:identity (:identity request)
:app-params {
:hx-get (bidi/path-for ssr-routes/only-routes
@@ -62,6 +63,6 @@
[:a {:href (bidi/path-for ssr-routes/only-routes
:company)}
"My Company"])
(main-content* {:client (:client (:session request))}))
(main-content* {:client (:client request)}))
"My Company"))

View File

@@ -44,23 +44,16 @@
client-id
vendor-id)))
(defn get-1099-companies [user {:keys [client-id] :as args}]
(let [clients (->> (dc/q '[:find ?c
:in $ ?user
:where [?c :client/code]
[(iol-ion.query/can-see-client? ?user ?c)]]
(dc/db conn) user)
(map first)
set)
(defn get-1099-companies [user {:keys [clients] :as args}]
(let [
results (cond
(and client-id
(can-see-client? user client-id))
clients
(dc/q '[:find
(pull ?c [:client/code :db/id])
(pull ?v vendor-read)
(sum ?a)
:with ?d
:in $ ?c vendor-read
:in $ [?c ...] vendor-read
:where
[?p :payment/client ?c]
[?p :payment/date ?d ]
@@ -70,7 +63,7 @@
[?p :payment/amount ?a]
[?p :payment/vendor ?v]]
(dc/db conn)
client-id
(set (map :db/id clients))
vendor-read)
(is-admin? user)

View File

@@ -45,10 +45,10 @@
"status" ['[?e :plaid-item/status ?sort-status]]}
args)
(limited-clients (:id args))
(:clients args)
(merge-query {:query {:in ['[?xx ...]]
:where ['[?e :plaid-item/client ?xx]]}
:args [ (set (map :db/id (limited-clients (:id args))))]})
:args [ (set (map :db/id (:clients args)))]})
(:client-id args)
(merge-query {:query {:in '[?client-id]

View File

@@ -12,7 +12,8 @@
[auto-ap.time :as atime]
[bidi.bidi :as bidi]
[config.core :refer [env]]
[datomic.api :as dc]))
[datomic.api :as dc]
[com.brunobonacci.mulog :as mu]))
(def grid-page {:id "report-table"
:nav (com/company-aside-nav)

View File

@@ -1,8 +1,7 @@
(ns auto-ap.ssr.company-dropdown
(:require
[auto-ap.datomic :refer [conn pull-many]]
[auto-ap.graphql.utils
:refer [assert-can-see-client cleanse-query is-admin?]]
[auto-ap.datomic :refer [conn pull-attr pull-many]]
[auto-ap.graphql.utils :refer [assert-can-see-client cleanse-query]]
[auto-ap.solr :as solr]
[auto-ap.ssr-routes :as ssr-routes]
[auto-ap.ssr.svg :as svg]
@@ -17,10 +16,14 @@
(for [{:keys [id name]} options]
[:li
[:div {:class "flex items-center pl-2 rounded hover:bg-green-100 dark:hover:bg-green-600"}
[:a {:href "#" :class "w-full py-2 ml-2 text-sm font-medium text-gray-900 rounded dark:text-gray-300"
"_" (hiccup/raw "on click set value of <#company-search-value/> to @data-value then send selected to #company-dropdown")
:data-value id}
[:a {:href "#" :class "w-full py-2 ml-2 text-sm font-medium text-gray-900 rounded dark:text-gray-300"
:hx-put (bidi/path-for ssr-routes/only-routes
:active-client
:request-method :put)
:hx-target "#company-dropdown"
:hx-headers (format "{\"x-clients\": \"[%d]\"}" id)
:hx-swap "outerHTML"
:hx-trigger "click"}
name]]])])
@@ -41,27 +44,29 @@
(defn dropdown-search-results [{:keys [identity] :as request}]
(html-response
(dropdown-search-results* {:options (get-clients identity (get (:query-params request) "search-text"))
:client (:client (:session request))})))
(dropdown-search-results* {:options (get-clients identity (get (:query-params request) "search-text"))})))
(defn dropdown [{:keys [client]}]
(defn dropdown [{:keys [client-selection client identity]}]
[:div#company-dropdown
{:hx-put (bidi/path-for ssr-routes/only-routes
:active-client
:request-method :put)
:hx-target "#company-dropdown"
:hx-include "#company-search-value"
:hx-swap "outerHTML"
:hx-trigger "selected"}
[:script
(hiccup/raw
"localStorage.setItem(\"last-client-id\", \""(:db/id client)"\")")]
"localStorage.setItem(\"last-client-id\", \"" (:db/id client) "\")" "\n"
"localStorage.setItem(\"last-selected-clients\", \"" client-selection "\")"
)]
[:div
[:button#company-dropdown-button { :class "text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:outline-none focus:ring-blue-300 font-medium rounded-lg text-sm px-4 py-2.5 text-center inline-flex items-center dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800"
:type "button"}
(if client
(:client/name client)
"All Companies")
(cond
(= :mine client-selection)
"My Companies"
(= :all client-selection)
"All Companies"
(and (sequential? client-selection)
(= 1 (count client-selection)))
(pull-attr (dc/db conn) :client/name (first client-selection))
:else
(str (count client-selection) " Companies"))
[:div.w-4.h-4.ml-2
svg/drop-down]]
[:div#company-dropdown-list.hidden {"_" (hiccup/raw "init call initCompanyDropdown()")
@@ -84,9 +89,21 @@
:hx-target "#company-search-results"
:hx-swap "innerHTML"} ]]
[:input#company-search-value {:type "hidden"
:name "search-client"}]]
:name "x-clients"}]]
[:div.divide-y.divide-gray-100
[:div#company-search-results {:class "h-48 px-3 pb-3 overflow-y-auto text-sm text-gray-700 dark:text-gray-200"}]
(when (= "admin" (:user/role identity))
[:div {:class "flex items-center pl-2 rounded hover:bg-green-100 dark:hover:bg-green-600"}
[:button {:class "w-full py-2 ml-2 text-sm font-medium text-gray-900 rounded dark:text-gray-300"
:hx-put (bidi/path-for ssr-routes/only-routes
:active-client
:request-method :put)
:hx-target "#company-dropdown"
:hx-headers "{\"x-clients\": \":mine\"}"
:hx-swap "outerHTML"
:hx-trigger "click"}
"Mine"]])
[:div {:class "flex items-center pl-2 rounded hover:bg-green-100 dark:hover:bg-green-600"}
[:button {:class "w-full py-2 ml-2 text-sm font-medium text-gray-900 rounded dark:text-gray-300"
@@ -94,6 +111,7 @@
:active-client
:request-method :put)
:hx-target "#company-dropdown"
:hx-headers "{\"x-clients\": \":all\"}"
:hx-swap "outerHTML"
:hx-trigger "click"}
"All"]]]
@@ -126,48 +144,10 @@ function initCompanyDropdown() {
")]]])
(defn active-client [{:keys [identity params] :as request}]
(let [client-search (or (:search-client params)
(get params "search-client"))
client-id (try (some-> client-search
(not-empty )
Long/parseLong)
(catch Exception _
nil))]
(when client-id
(assert-can-see-client identity client-id))
(let [new-session (assoc (:session request)
:client
(when client-id
(dc/pull (dc/db conn) [:db/id :client/name :client/code] client-id))
:clients
(cond (int? client-id)
[(dc/pull (dc/db conn) [:db/id :client/name :client/code] client-id)]
(= ":mine" client-search)
(->> (dc/q '[:find (pull ?c [:db/id :client/name :client/code])
:in $ ?u
:where [?u :user/clients ?c]]
(dc/db conn)
(:db/id identity))
(map first))
(and (or (empty? client-search)
(= ":all" client-search))
(is-admin? identity))
(->> (dc/q '[:find (pull ?c [:db/id :client/name :client/code])
:in $ ?u
:where [?c :client/code]]
(dc/db conn)
(:db/id identity))
(map first))))]
(assoc
(html-response
(dropdown {:client (:client new-session)
:identity identity}))
:session
new-session
:headers
{"hx-trigger" "clientSelected"}))))
(assoc
(html-response
(dropdown {:client-selection (:client-selection (:session request))
:client (:client request)
:identity identity}))
:headers
{"hx-trigger" "clientSelected"}))

View File

@@ -8,7 +8,7 @@
[auto-ap.ssr.svg :as svg]
[bidi.bidi :as bidi]))
(defn navbar- [{:keys [client identity]}]
(defn navbar- [{:keys [client-selection client identity]}]
[:nav {:class "fixed z-30 w-full bg-white border-b border-gray-200 dark:bg-gray-800 dark:border-gray-700"}
[:div {:class "px-3 py-3 lg:px-5 lg:pl-3"}
[:div {:class "flex items-center justify-between"}
@@ -40,6 +40,6 @@
:hx-target "#modal-holder"
:hx-swap "outerHTML"}
svg/search)
(cd/dropdown {:client client :identity identity})
(cd/dropdown {:client-selection client-selection :client client :identity identity})
(user-dropdown/dropdown {:identity identity})]]]])

View File

@@ -5,9 +5,10 @@
[hiccup2.core :as hiccup]
[auto-ap.ssr.svg :as svg]))
(defn page- [{:keys [nav page-specific active-client identity app-params] :or {app-params {}}} & children]
(defn page- [{:keys [nav page-specific client client-selection identity app-params] :or {app-params {}}} & children]
[:div#app
(navbar- {:client active-client
(navbar- {:client-selection client-selection
:client client
:identity identity})
[:div#app-contents.flex.pt-16.overflow-hidden (assoc app-params :hx-disinherit "*")
(left-aside- {:nav nav

View File

@@ -8,7 +8,9 @@
[auto-ap.ssr-routes :as ssr-routes]
[cemerick.url :as url]
[clojure.string :as str]
[auto-ap.ssr.svg :as svg]))
[auto-ap.ssr.svg :as svg]
[unilog.context :as lc]
[com.brunobonacci.mulog :as mu]))
(defn row* [gridspec user entity {:keys [flash? delete-after-settle?] :as options}]
(let [cells (mapv (fn [header]
@@ -51,16 +53,15 @@
))
"default sort"))
(defn table* [grid-spec user {:keys [start per-page client flash-id sort request] :as params}]
(defn table* [grid-spec user {:keys [start per-page clients flash-id sort] :as params}]
(let [start (or start 0)
per-page (or per-page 30)
[entities total] ((:fetch-page grid-spec)
user
{:start start
:per-page per-page
:client-id (:db/id client)
:sort sort
:request request})]
:clients clients
:sort sort})]
(com/data-grid-card {:id (:id grid-spec)
:title (:title grid-spec)
:route (:route grid-spec)
@@ -161,7 +162,9 @@
q-sort (assoc :sort (parse-sort grid-spec q-sort))
(not-empty q-toggle-sort) (update :sort #(toggle-sort grid-spec % q-toggle-sort) )
(:session request) (assoc :session (:session request))
(:client (:session request)) (assoc :client (:client (:session request))))))
(:client-selection (:session request)) (assoc :client-selection (:client-selection (:session request)))
(:clients request) (assoc :clients (:clients request))
(:client request) (assoc :client (:client request)))))
(defn table [grid-spec {:keys [query-params hx-query-params identity session] :as request}]
(let [params (extract-params grid-spec request)
@@ -177,7 +180,8 @@
(base-page
request
(com/page {:nav (:nav grid-spec)
:active-client (:client (:session request))
:client-selection (:client-selection (:session request))
:client (:client request)
:identity (:identity request)}
(apply com/breadcrumbs {} (:breadcrumbs grid-spec))
(table* grid-spec

View File

@@ -419,7 +419,8 @@ invoice_dropzone = new Dropzone(\"#invoice\", {
(base-page
request
(com/page {:nav (com/admin-aside-nav)
:active-client (:client (:session request))
:client-selection (:client-selection (:session request))
:client (:client request)
:identity (:identity request)
:app-params {:hx-get (bidi/path-for ssr-routes/only-routes
:invoice-glimpse)

View File

@@ -41,7 +41,7 @@
:seen-by-client? s})
ors))))
(defn transaction-recommendations [identity selected-client & {:keys [after]}]
(defn transaction-recommendations [identity clients & {:keys [after]}]
(let [visible-clients (visible-clients identity)]
(->>
(dc/qseq {:query '[:find (pull ?t pull-expr)
@@ -56,9 +56,8 @@
:args [(dc/db conn)
(iol-ion.query/recent-date 120)
(if selected-client
[selected-client]
visible-clients)
(map :db/id clients)
pull-expr]})
(map first)
(drop-while (fn [x]
@@ -273,8 +272,8 @@
[:td (format "%.1f%%" (* 100 (double score)))]]))]]
[:div])))))
(defn transaction-rows* [{:keys [selected-client identity after]}]
(let [recommendations (transaction-recommendations identity selected-client :after after)]
(defn transaction-rows* [{:keys [clients identity after]}]
(let [recommendations (transaction-recommendations identity clients :after after)]
(if (seq recommendations)
(for [r recommendations
:let [last? (= r (last recommendations))]]
@@ -282,13 +281,13 @@
[:tr [:td.has-text-centered.has-text-gray {:colspan 7 }
[:i "That's the last of 'em!"]]])))
(defn transaction-rows [{:keys [session identity route-params]}]
(html-response (transaction-rows* {:selected-client (-> session :client :db/id)
(defn transaction-rows [{:keys [session identity route-params clients]}]
(html-response (transaction-rows* {:clients clients
:identity identity
:after (:after route-params)})))
(defn insight-table* [{:keys [selected-client identity]}]
(let [recommendations (transaction-recommendations identity selected-client)]
(defn insight-table* [{:keys [clients identity]}]
(let [recommendations (transaction-recommendations identity clients)]
(com/data-grid-card {:id "insight-table"
:title "Transaction Insights"
:route :transaction-insight-table
@@ -305,16 +304,16 @@
(com/data-grid-header {:style {:width "8em"}} "Amount")
(com/data-grid-header {})]})))
(defn insight-table [{:keys [session identity]}]
(html-response (insight-table* {:selected-client
(-> session :client :db/id)
(defn insight-table [{:keys [session identity clients]}]
(html-response (insight-table* {:clients clients
:identity identity})))
(defn page [{:keys [identity matched-route session] :as request}]
(base-page
request
(com/page {:nav (com/main-aside-nav)
:active-client (:client (:session request))
:client-selection (:client-selection (:session request))
:client (:client request)
:identity (:identity request)
:app-params {:hx-get (bidi/path-for ssr-routes/only-routes
:transaction-insights)