cleans up grids

This commit is contained in:
2024-11-18 19:41:54 -08:00
parent ad06418a69
commit a8c7c7eb8e
31 changed files with 842 additions and 714 deletions

View File

@@ -308,9 +308,9 @@
(fn [request] (fn [request]
(let [valid-clients (extract-client-ids (:clients request) (let [valid-clients (extract-client-ids (:clients request)
(:client request) (:client request)
(:client-id (:parsed-query-params request)) (:client-id (:query-params request))
(when (:client-code (:parsed-query-params request)) (when (:client-code (:query-params request))
[:client/code (:client-code (:parsed-query-params request))])) [:client/code (:client-code (:query-params request))]))
trimmed-clients (->> valid-clients (take 20) set)] trimmed-clients (->> valid-clients (take 20) set)]
(handler (assoc request :valid-client-ids valid-clients (handler (assoc request :valid-client-ids valid-clients
:valid-trimmed-client-ids trimmed-clients :valid-trimmed-client-ids trimmed-clients

View File

@@ -9,12 +9,6 @@
(fn [request] (fn [request]
(handler (assoc request :parsed-query-params (:query-params request))))) (handler (assoc request :parsed-query-params (:query-params request)))))
(defn wrap-parse-query-params [handler parser]
(fn parsed-handler [request]
(handler (assoc request :parsed-query-params (parser (->> (concat (:hx-query-params request) (:query-params request))
(map (fn [[k v]] [(keyword k) v]))
(into {})))))))
(defn parse-key [k parser] (defn parse-key [k parser]
(fn [query-params] (fn [query-params]
(if (contains? query-params k) (if (contains? query-params k)
@@ -24,9 +18,6 @@
(defn parse-date [d] (defn parse-date [d]
(atime/parse d atime/normal-date)) (atime/parse d atime/normal-date))
(defn parse-keyword [ns name]
(some->> name (keyword ns)))
(defn parse-sort [grid-spec q] (defn parse-sort [grid-spec q]
(if (not-empty q) (if (not-empty q)
(->> (->>

View File

@@ -1,47 +1,39 @@
(ns auto-ap.ssr.admin.accounts (ns auto-ap.ssr.admin.accounts
(:require (:require
[auto-ap.datomic [auto-ap.datomic
:refer [add-sorter-fields :refer [add-sorter-fields apply-pagination apply-sort-3 audit-transact
apply-pagination conn merge-query pull-attr pull-many query2]]
apply-sort-3 [auto-ap.query-params :as query-params :refer [wrap-copy-qp-pqp]]
audit-transact
conn
merge-query
pull-attr
pull-many
query2]]
[auto-ap.query-params :as query-params]
[auto-ap.routes.utils [auto-ap.routes.utils
:refer [wrap-admin wrap-client-redirect-unauthenticated]] :refer [wrap-admin wrap-client-redirect-unauthenticated]]
[auto-ap.solr :as solr] [auto-ap.solr :as solr]
[auto-ap.ssr-routes :as ssr-routes] [auto-ap.ssr-routes :as ssr-routes]
[auto-ap.ssr.components :as com] [auto-ap.ssr.components :as com]
[auto-ap.ssr.form-cursor :as fc] [auto-ap.ssr.form-cursor :as fc]
[auto-ap.ssr.grid-page-helper :as helper] [auto-ap.ssr.grid-page-helper :as helper :refer [wrap-apply-sort]]
[auto-ap.ssr.hx :as hx] [auto-ap.ssr.hx :as hx]
[auto-ap.ssr.nested-form-params :refer [wrap-nested-form-params]] [auto-ap.ssr.nested-form-params :refer [wrap-nested-form-params]]
[auto-ap.ssr.payments :refer [wrap-status-from-source]]
[auto-ap.ssr.svg :as svg] [auto-ap.ssr.svg :as svg]
[auto-ap.ssr.utils [auto-ap.ssr.utils
:refer [apply-middleware-to-all-handlers :refer [apply-middleware-to-all-handlers clj-date-schema
entity-id default-grid-fields-schema entity-id field-validation-error
field-validation-error form-validation-error html-response main-transformer many-entity
form-validation-error modal-response ref->enum-schema ref->select-options strip temp-id
html-response wrap-entity wrap-form-4xx-2 wrap-merge-prior-hx
main-transformer
many-entity
modal-response
ref->enum-schema
ref->select-options
strip
temp-id
wrap-entity
wrap-form-4xx-2
wrap-schema-enforce]] wrap-schema-enforce]]
[bidi.bidi :as bidi] [bidi.bidi :as bidi]
[clojure.string :as str] [clojure.string :as str]
[datomic.api :as dc] [datomic.api :as dc]
[malli.core :as mc])) [malli.core :as mc]))
(def query-schema (mc/schema
[:maybe
(into [:map {:date-range [:date-range :start-date :end-date]}
[:type {:optional true} [:maybe (ref->enum-schema "account-type")]]
[:name {:optional true} [:maybe [:string {:decode/string strip}]]]
[:code {:optional true} [:maybe nat-int?]]]
default-grid-fields-schema)]))
(defn filters [request] (defn filters [request]
[:form {"hx-trigger" "change delay:500ms, keyup changed from:.hot-filter delay:1000ms" [:form {"hx-trigger" "change delay:500ms, keyup changed from:.hot-filter delay:1000ms"
"hx-get" (bidi/path-for ssr-routes/only-routes "hx-get" (bidi/path-for ssr-routes/only-routes
@@ -54,7 +46,7 @@
(com/text-input {:name "name" (com/text-input {:name "name"
:id "name" :id "name"
:class "hot-filter" :class "hot-filter"
:value (:name (:parsed-query-params request)) :value (:name (:query-params request))
:placeholder "Cash" :placeholder "Cash"
:size :small})) :size :small}))
@@ -62,12 +54,13 @@
(com/text-input {:name "code" (com/text-input {:name "code"
:id "code" :id "code"
:class "hot-filter" :class "hot-filter"
:value (:code (:parsed-query-params request)) :value (:code (:query-params request))
:placeholder "11101" :placeholder "11101"
:size :small})) :size :small}))
(com/field {:label "Type"} (com/field {:label "Type"}
(com/radio-card {:size :small (com/radio-card {:size :small
:name "type" :name "type"
:value (:type (:query-params request))
:options [{:value "" :options [{:value ""
:content "All"} :content "All"}
{:value "dividend" {:value "dividend"
@@ -99,7 +92,7 @@
:db/id]}]) :db/id]}])
(defn fetch-ids [db request] (defn fetch-ids [db request]
(let [query-params (:parsed-query-params request) (let [query-params (:query-params request)
query (cond-> {:query {:find [] query (cond-> {:query {:find []
:in '[$] :in '[$]
:where '[]} :where '[]}
@@ -127,10 +120,8 @@
(some->> query-params :type) (some->> query-params :type)
(merge-query {:query {:find [] (merge-query {:query {:find []
:in ['?rir] :in ['?r]
:where ['[?e :account/type ?r] :where ['[?e :account/type ?r] ]}
'[?r :db/ident ?ri]
'[(name ?ri) ?rir] ]}
:args [(some->> query-params :type)]}) :args [(some->> query-params :type)]})
true true
@@ -161,9 +152,6 @@
:nav com/admin-aside-nav :nav com/admin-aside-nav
:page-specific-nav filters :page-specific-nav filters
:fetch-page fetch-page :fetch-page fetch-page
:parse-query-params (comp
(query-params/parse-key :code query-params/parse-long)
(helper/default-parse-query-params grid-page))
:action-buttons (fn [_] :action-buttons (fn [_]
[(com/button {:hx-get (str (bidi/path-for ssr-routes/only-routes [(com/button {:hx-get (str (bidi/path-for ssr-routes/only-routes
:admin-account-new-dialog)) :admin-account-new-dialog))
@@ -183,6 +171,7 @@
"Accounts"]] "Accounts"]]
:title "Accounts" :title "Accounts"
:entity-name "Account" :entity-name "Account"
:query-schema query-schema
:route :admin-account-table :route :admin-account-table
:headers [{:key "code" :headers [{:key "code"
:name "Code" :name "Code"
@@ -431,25 +420,31 @@
(def key->handler (def key->handler
(apply-middleware-to-all-handlers (apply-middleware-to-all-handlers
(->> (->>
{:admin-accounts (helper/page-route grid-page) {:admin-accounts (helper/page-route grid-page)
:admin-account-table (helper/table-route grid-page) :admin-account-table (helper/table-route grid-page)
:admin-account-client-override-new (-> new-client-override :admin-account-client-override-new (-> new-client-override
(wrap-schema-enforce :query-schema [:map (wrap-schema-enforce :query-schema [:map
[:index {:optional true [:index {:optional true
:default 0} [nat-int? {:default 0}]]]) :default 0} [nat-int? {:default 0}]]])
wrap-admin wrap-client-redirect-unauthenticated) wrap-admin wrap-client-redirect-unauthenticated)
:admin-account-save (-> account-save :admin-account-save (-> account-save
(wrap-entity [:form-params :db/id] default-read) (wrap-entity [:form-params :db/id] default-read)
(wrap-schema-enforce :form-schema form-schema) (wrap-schema-enforce :form-schema form-schema)
(wrap-nested-form-params) (wrap-nested-form-params)
(wrap-form-4xx-2 (wrap-entity account-dialog [:form-params :db/id] default-read))) (wrap-form-4xx-2 (wrap-entity account-dialog [:form-params :db/id] default-read)))
:admin-account-edit-dialog (-> account-dialog :admin-account-edit-dialog (-> account-dialog
(wrap-entity [:route-params :db/id] default-read) (wrap-entity [:route-params :db/id] default-read)
(wrap-schema-enforce :route-schema [:map [:db/id entity-id]])) (wrap-schema-enforce :route-schema [:map [:db/id entity-id]]))
:admin-account-new-dialog account-dialog}) :admin-account-new-dialog account-dialog})
(fn [h] (fn [h]
(-> h (-> h
(wrap-admin) (wrap-copy-qp-pqp)
(wrap-client-redirect-unauthenticated))))) (wrap-apply-sort grid-page)
(wrap-merge-prior-hx)
(wrap-status-from-source)
(wrap-schema-enforce :query-schema query-schema)
(wrap-schema-enforce :hx-schema query-schema)
(wrap-admin)
(wrap-client-redirect-unauthenticated)))))

View File

@@ -85,6 +85,7 @@
(filter is-background-job?) (filter is-background-job?)
(map ecs-task->job))] (map ecs-task->job))]
[jobs (count jobs)])) [jobs (count jobs)]))
(def query-schema (mc/schema [:map ]))
(def grid-page (def grid-page
(helper/build {:id "job-table" (helper/build {:id "job-table"
@@ -104,6 +105,7 @@
"Background Jobs"]] "Background Jobs"]]
:title "Jobs" :title "Jobs"
:entity-name "Job" :entity-name "Job"
:query-schema query-schema
:route :admin-job-table :route :admin-job-table
:headers [ :headers [
{:key "start" {:key "start"

View File

@@ -216,8 +216,6 @@
:nav com/admin-aside-nav :nav com/admin-aside-nav
:page-specific-nav filters :page-specific-nav filters
:fetch-page fetch-page :fetch-page fetch-page
:parse-query-params (fn [p]
(mc/decode query-schema p main-transformer))
:action-buttons (fn [_] :action-buttons (fn [_]
[(com/button {:hx-get (str (bidi/path-for ssr-routes/only-routes ::route/new-dialog)) [(com/button {:hx-get (str (bidi/path-for ssr-routes/only-routes ::route/new-dialog))
:color :primary} :color :primary}
@@ -237,6 +235,7 @@
"Clients"]] "Clients"]]
:title "Clients" :title "Clients"
:entity-name "Client" :entity-name "Client"
:query-schema query-schema
:route ::route/table :route ::route/table
:headers [{:key "name" :headers [{:key "name"
:name "Name" :name "Name"
@@ -1848,8 +1847,8 @@
(def key->handler (def key->handler
(apply-middleware-to-all-handlers (apply-middleware-to-all-handlers
{::route/page (helper/page-route grid-page :parse-query-params? false) {::route/page (helper/page-route grid-page)
::route/table (helper/table-route grid-page :parse-query-params? false) ::route/table (helper/table-route grid-page)
::route/new-location (add-new-primitive-handler [:step-params :client/locations] ::route/new-location (add-new-primitive-handler [:step-params :client/locations]
"" ""
location-row) location-row)

View File

@@ -1,31 +1,38 @@
(ns auto-ap.ssr.admin.import-batch (ns auto-ap.ssr.admin.import-batch
(:require (:require
[auto-ap.client-routes :as client-routes]
[auto-ap.datomic [auto-ap.datomic
:refer [add-sorter-fields :refer [add-sorter-fields apply-pagination apply-sort-3 conn merge-query
apply-pagination pull-many query2]]
apply-sort-3 [auto-ap.query-params :refer [wrap-copy-qp-pqp]]
conn
merge-query
pull-many
query2]]
[auto-ap.routes.admin.import-batch :as route] [auto-ap.routes.admin.import-batch :as route]
[auto-ap.routes.utils [auto-ap.routes.utils
:refer [wrap-admin wrap-client-redirect-unauthenticated]] :refer [wrap-admin wrap-client-redirect-unauthenticated]]
[auto-ap.ssr-routes :as ssr-routes] [auto-ap.ssr-routes :as ssr-routes]
[auto-ap.ssr.components :as com] [auto-ap.ssr.components :as com]
[auto-ap.ssr.components.date-range :refer [date-range-field]] [auto-ap.ssr.components.date-range :refer [date-range-field]]
[auto-ap.ssr.grid-page-helper :as helper] [auto-ap.ssr.grid-page-helper :as helper :refer [wrap-apply-sort]]
[auto-ap.ssr.svg :as svg]
[auto-ap.ssr.utils [auto-ap.ssr.utils
:refer [apply-middleware-to-all-handlers ref->select-options]] :refer [apply-middleware-to-all-handlers clj-date-schema
default-grid-fields-schema ref->select-options wrap-merge-prior-hx
wrap-schema-enforce]]
[auto-ap.time :as atime] [auto-ap.time :as atime]
[bidi.bidi :as bidi] [bidi.bidi :as bidi]
[clj-time.coerce :as coerce]
[datomic.api :as dc]
[clj-time.coerce :as c] [clj-time.coerce :as c]
[auto-ap.logging :as alog] [datomic.api :as dc]
[hiccup.util :as hu] [hiccup.util :as hu]
[auto-ap.client-routes :as client-routes] [malli.core :as mc]))
[auto-ap.ssr.svg :as svg]))
(def query-schema (mc/schema
[:maybe
(into [:map {:date-range [:date-range :start-date :end-date]}
[:start-date {:optional true}
[:maybe clj-date-schema]]
[:end-date {:optional true}
[:maybe clj-date-schema]]
[:client {:optional true :default nil} [:maybe [:entity-map {:pull [:db/id :client/name]}]]]]
default-grid-fields-schema)]))
(defn filters [request] (defn filters [request]
[:form {"hx-trigger" "change delay:500ms, keyup changed from:.hot-filter delay:1000ms" [:form {"hx-trigger" "change delay:500ms, keyup changed from:.hot-filter delay:1000ms"
@@ -35,13 +42,13 @@
"hx-indicator" "#entity-table"} "hx-indicator" "#entity-table"}
[:fieldset.space-y-6 [:fieldset.space-y-6
(date-range-field {:value {:start (:start-date (:parsed-query-params request)) (date-range-field {:value {:start (:start-date (:query-params request))
:end (:end-date (:parsed-query-params request))} :end (:end-date (:query-params request))}
:id "date-range"}) :id "date-range"})
(com/field {:label "Source"} (com/field {:label "Source"}
(com/select {:name "source" (com/select {:name "source"
:class "hot-filter w-full" :class "hot-filter w-full"
:value (:source (:parsed-query-params request)) :value (:source (:query-params request))
:placeholder "" :placeholder ""
:options (ref->select-options "import-source" :allow-nil? true)})) :options (ref->select-options "import-source" :allow-nil? true)}))
@@ -49,7 +56,7 @@
(com/text-input {:name "code" (com/text-input {:name "code"
:id "code" :id "code"
:class "hot-filter" :class "hot-filter"
:value (:code (:parsed-query-params request)) :value (:code (:query-params request))
:placeholder "11101" :placeholder "11101"
:size :small}))]]) :size :small}))]])
@@ -63,7 +70,7 @@
[:import-batch/status :xform iol-ion.query/ident] [:db/ident]}]) [:import-batch/status :xform iol-ion.query/ident] [:db/ident]}])
(defn fetch-ids [db request] (defn fetch-ids [db request]
(let [query-params (:parsed-query-params request) (let [query-params (:query-params request)
query (cond-> {:query {:find [] query (cond-> {:query {:find []
:in '[$ ] :in '[$ ]
:where '[]} :where '[]}
@@ -134,11 +141,9 @@
svg/external-link)]) svg/external-link)])
:oob-render :oob-render
(fn [request] (fn [request]
[(assoc-in (date-range-field {:value {:start (:start-date (:parsed-query-params request)) [(assoc-in (date-range-field {:value {:start (:start-date (:query-params request))
:end (:end-date (:parsed-query-params request))} :end (:end-date (:query-params request))}
:id "date-range"}) [1 :hx-swap-oob] true)]) :id "date-range"}) [1 :hx-swap-oob] true)])
:parse-query-params (comp
(helper/default-parse-query-params grid-page))
:breadcrumbs [[:a {:href (bidi/path-for ssr-routes/only-routes :breadcrumbs [[:a {:href (bidi/path-for ssr-routes/only-routes
:admin)} :admin)}
"Admin"] "Admin"]
@@ -148,6 +153,7 @@
"Import Batches"]] "Import Batches"]]
:title "Import Batches" :title "Import Batches"
:entity-name "Batch" :entity-name "Batch"
:query-schema query-schema
:route ::route/table :route ::route/table
:headers [{:key "date" :headers [{:key "date"
:name "Date" :name "Date"
@@ -184,5 +190,11 @@
::route/table (helper/table-route grid-page)}) ::route/table (helper/table-route grid-page)})
(fn [h] (fn [h]
(-> h (-> h
(wrap-copy-qp-pqp)
(wrap-apply-sort grid-page)
(wrap-merge-prior-hx)
(wrap-schema-enforce :query-schema query-schema)
(wrap-schema-enforce :hx-schema query-schema)
(wrap-admin) (wrap-admin)
(wrap-client-redirect-unauthenticated))))) (wrap-client-redirect-unauthenticated)))))

View File

@@ -1,32 +1,45 @@
(ns auto-ap.ssr.admin.sales-summaries (ns auto-ap.ssr.admin.sales-summaries
(:require [auto-ap.datomic (:require
[auto-ap.datomic
:refer [apply-pagination apply-sort-3 conn merge-query pull-many :refer [apply-pagination apply-sort-3 conn merge-query pull-many
query2]] query2]]
[auto-ap.datomic.accounts :as d-accounts] [auto-ap.datomic.accounts :as d-accounts]
[auto-ap.graphql.utils :refer [extract-client-ids]] [auto-ap.graphql.utils :refer [extract-client-ids]]
[auto-ap.routes.admin.sales-summaries :as route] [auto-ap.query-params :refer [wrap-copy-qp-pqp]]
[auto-ap.routes.utils [auto-ap.routes.admin.sales-summaries :as route]
[auto-ap.routes.utils
:refer [wrap-admin wrap-client-redirect-unauthenticated]] :refer [wrap-admin wrap-client-redirect-unauthenticated]]
[auto-ap.ssr-routes :as ssr-routes] [auto-ap.ssr-routes :as ssr-routes]
[auto-ap.ssr.common-handlers :refer [add-new-entity-handler]] [auto-ap.ssr.common-handlers :refer [add-new-entity-handler]]
[auto-ap.ssr.components :as com] [auto-ap.ssr.components :as com]
[auto-ap.ssr.components.multi-modal :as mm] [auto-ap.ssr.components.multi-modal :as mm]
[auto-ap.ssr.form-cursor :as fc] [auto-ap.ssr.form-cursor :as fc]
[auto-ap.ssr.grid-page-helper :as helper] [auto-ap.ssr.grid-page-helper :as helper :refer [wrap-apply-sort]]
[auto-ap.ssr.hx :as hx] [auto-ap.ssr.hx :as hx]
[auto-ap.ssr.svg :as svg] [auto-ap.ssr.svg :as svg]
[auto-ap.ssr.utils [auto-ap.ssr.utils
:refer [apply-middleware-to-all-handlers entity-id html-response :refer [apply-middleware-to-all-handlers clj-date-schema
money strip temp-id wrap-schema-enforce]] default-grid-fields-schema entity-id html-response money
[auto-ap.time :as atime] strip temp-id wrap-merge-prior-hx wrap-schema-enforce]]
[bidi.bidi :as bidi] [auto-ap.time :as atime]
[clj-time.coerce :as c] [bidi.bidi :as bidi]
[clojure.string :as str] [clj-time.coerce :as c]
[datomic.api :as dc] [clojure.string :as str]
[hiccup.util :as hu] [datomic.api :as dc]
[iol-ion.query :refer [dollars=]] [hiccup.util :as hu]
[malli.core :as mc] [iol-ion.query :refer [dollars=]]
[malli.util :as mut])) [malli.core :as mc]
[malli.util :as mut]))
(def query-schema (mc/schema
[:maybe
(into [:map {:date-range [:date-range :start-date :end-date]}
[:start-date {:optional true}
[:maybe clj-date-schema]]
[:end-date {:optional true}
[:maybe clj-date-schema]] ]
default-grid-fields-schema)]))
(defn filters [request] (defn filters [request]
[:form {"hx-trigger" "change delay:500ms, keyup changed from:.hot-filter delay:1000ms" [:form {"hx-trigger" "change delay:500ms, keyup changed from:.hot-filter delay:1000ms"
@@ -36,13 +49,13 @@
"hx-indicator" "#entity-table"} "hx-indicator" "#entity-table"}
#_[:fieldset.space-y-6 #_[:fieldset.space-y-6
(date-range-field {:value {:start (:start-date (:parsed-query-params request)) (date-range-field {:value {:start (:start-date (:query-params request))
:end (:end-date (:parsed-query-params request))} :end (:end-date (:query-params request))}
:id "date-range"}) :id "date-range"})
(com/field {:label "Source"} (com/field {:label "Source"}
(com/select {:name "source" (com/select {:name "source"
:class "hot-filter w-full" :class "hot-filter w-full"
:value (:source (:parsed-query-params request)) :value (:source (:query-params request))
:placeholder "" :placeholder ""
:options (ref->select-options "import-source" :allow-nil? true)})) :options (ref->select-options "import-source" :allow-nil? true)}))
@@ -50,7 +63,7 @@
(com/text-input {:name "code" (com/text-input {:name "code"
:id "code" :id "code"
:class "hot-filter" :class "hot-filter"
:value (:code (:parsed-query-params request)) :value (:code (:query-params request))
:placeholder "11101" :placeholder "11101"
:size :small}))]]) :size :small}))]])
@@ -69,7 +82,7 @@
} ]) ;; TODO } ]) ;; TODO
(defn fetch-ids [db request] (defn fetch-ids [db request]
(let [query-params (:parsed-query-params request) (let [query-params (:query-params request)
valid-clients (extract-client-ids (:clients request) valid-clients (extract-client-ids (:clients request)
(:client request) (:client request)
(:client-id query-params) (:client-id query-params)
@@ -159,6 +172,7 @@
:nav com/admin-aside-nav :nav com/admin-aside-nav
:fetch-page fetch-page :fetch-page fetch-page
:page-specific-nav filters :page-specific-nav filters
:query-schema query-schema
:row-buttons (fn [_ entity] :row-buttons (fn [_ entity]
[(com/icon-button {:hx-get (bidi/path-for ssr-routes/only-routes [(com/icon-button {:hx-get (bidi/path-for ssr-routes/only-routes
::route/edit-wizard ::route/edit-wizard
@@ -166,11 +180,9 @@
svg/pencil)]) svg/pencil)])
:oob-render :oob-render
(fn [request] (fn [request]
[#_(assoc-in (date-range-field {:value {:start (:start-date (:parsed-query-params request)) [#_(assoc-in (date-range-field {:value {:start (:start-date (:query-params request))
:end (:end-date (:parsed-query-params request))} :end (:end-date (:query-params request))}
:id "date-range"}) [1 :hx-swap-oob] true)]) ;; TODO :id "date-range"}) [1 :hx-swap-oob] true)]) ;; TODO
:parse-query-params (comp
(helper/default-parse-query-params grid-page))
:breadcrumbs [[:a {:href (bidi/path-for ssr-routes/only-routes :breadcrumbs [[:a {:href (bidi/path-for ssr-routes/only-routes
:admin)} :admin)}
"Admin"] "Admin"]
@@ -516,26 +528,33 @@
{::route/page (helper/page-route grid-page) {::route/page (helper/page-route grid-page)
::route/table (helper/table-route grid-page) ::route/table (helper/table-route grid-page)
::route/edit-wizard (-> mm/open-wizard-handler ::route/edit-wizard (-> mm/open-wizard-handler
(mm/wrap-wizard edit-wizard) (mm/wrap-wizard edit-wizard)
(mm/wrap-init-multi-form-state initial-edit-wizard-state) (mm/wrap-init-multi-form-state initial-edit-wizard-state)
(wrap-schema-enforce :route-schema [:map [:db/id entity-id]])) (wrap-schema-enforce :route-schema [:map [:db/id entity-id]]))
::route/edit-wizard-navigate (-> mm/next-handler ::route/edit-wizard-navigate (-> mm/next-handler
(mm/wrap-wizard edit-wizard) (mm/wrap-wizard edit-wizard)
(mm/wrap-decode-multi-form-state)) (mm/wrap-decode-multi-form-state))
::route/new-summary-item (-> (add-new-entity-handler [:step-params :sales-summary/items] ::route/new-summary-item (-> (add-new-entity-handler [:step-params :sales-summary/items]
(fn render [cursor request] (fn render [cursor request]
(sales-summary-item-row* (sales-summary-item-row*
{:value cursor {:value cursor
:client-id (:client-id (:query-params request)) })) :client-id (:client-id (:query-params request))}))
(fn build-new-row [base _] (fn build-new-row [base _]
(assoc base :sales-summary-item/manual? true))) (assoc base :sales-summary-item/manual? true)))
(wrap-schema-enforce :query-schema [:map (wrap-schema-enforce :query-schema [:map
[:client-id {:optional true} [:client-id {:optional true}
[:maybe entity-id]]])) [:maybe entity-id]]]))
::route/edit-wizard-submit (-> mm/submit-handler ::route/edit-wizard-submit (-> mm/submit-handler
(mm/wrap-wizard edit-wizard) (mm/wrap-wizard edit-wizard)
(mm/wrap-decode-multi-form-state))}) (mm/wrap-decode-multi-form-state))})
(fn [h] (fn [h]
(-> h (-> h
(wrap-copy-qp-pqp)
(wrap-apply-sort grid-page)
(wrap-merge-prior-hx)
(wrap-schema-enforce :query-schema query-schema)
(wrap-schema-enforce :hx-schema query-schema)
(wrap-admin) (wrap-admin)
(wrap-client-redirect-unauthenticated))))) (wrap-client-redirect-unauthenticated)))))

View File

@@ -1,43 +1,49 @@
(ns auto-ap.ssr.admin.transaction-rules (ns auto-ap.ssr.admin.transaction-rules
(:require [auto-ap.datomic (:require
[auto-ap.datomic
:refer [add-sorter-fields apply-pagination apply-sort-3 :refer [add-sorter-fields apply-pagination apply-sort-3
audit-transact conn merge-query pull-attr pull-many audit-transact conn merge-query pull-attr pull-many
query2 remove-nils]] query2 remove-nils]]
[auto-ap.datomic.accounts :as d-accounts] [auto-ap.datomic.accounts :as d-accounts]
[auto-ap.datomic.transactions :as d-transactions] [auto-ap.datomic.transactions :as d-transactions]
[auto-ap.graphql.utils :refer [extract-client-ids]] [auto-ap.graphql.utils :refer [extract-client-ids]]
[auto-ap.logging :as alog] [auto-ap.query-params :as query-params :refer [wrap-copy-qp-pqp]]
[auto-ap.query-params :as query-params] [auto-ap.routes.admin.transaction-rules :as route]
[auto-ap.routes.admin.transaction-rules :as route] [auto-ap.routes.utils
[auto-ap.routes.utils
:refer [wrap-admin wrap-client-redirect-unauthenticated]] :refer [wrap-admin wrap-client-redirect-unauthenticated]]
[auto-ap.rule-matching :as rm] [auto-ap.rule-matching :as rm]
[auto-ap.solr :as solr] [auto-ap.solr :as solr]
[auto-ap.ssr-routes :as ssr-routes] [auto-ap.ssr-routes :as ssr-routes]
[auto-ap.ssr.common-handlers :refer [add-new-entity-handler]] [auto-ap.ssr.common-handlers :refer [add-new-entity-handler]]
[auto-ap.ssr.company :refer [bank-account-typeahead*]] [auto-ap.ssr.company :refer [bank-account-typeahead*]]
[auto-ap.ssr.components :as com] [auto-ap.ssr.components :as com]
[auto-ap.ssr.components.multi-modal :as mm] [auto-ap.ssr.components.multi-modal :as mm]
[auto-ap.ssr.form-cursor :as fc] [auto-ap.ssr.form-cursor :as fc]
[auto-ap.ssr.grid-page-helper :as helper] [auto-ap.ssr.grid-page-helper :as helper :refer [wrap-apply-sort]]
[auto-ap.ssr.hx :as hx] [auto-ap.ssr.hx :as hx]
[auto-ap.ssr.svg :as svg] [auto-ap.ssr.svg :as svg]
[auto-ap.ssr.utils [auto-ap.ssr.utils
:refer [apply-middleware-to-all-handlers entity-id :refer [apply-middleware-to-all-handlers
default-grid-fields-schema entity-id
field-validation-error form-validation-error field-validation-error form-validation-error
html-response many-entity modal-response money percentage html-response many-entity modal-response money percentage
ref->enum-schema ref->radio-options regex temp-id ref->enum-schema ref->radio-options regex temp-id
wrap-entity wrap-schema-enforce]] wrap-entity wrap-merge-prior-hx wrap-schema-enforce]]
[auto-ap.time :as atime] [auto-ap.time :as atime]
[auto-ap.utils :refer [dollars=]] [auto-ap.utils :refer [dollars=]]
[bidi.bidi :as bidi] [bidi.bidi :as bidi]
[clj-time.coerce :as coerce] [clj-time.coerce :as coerce]
[clojure.set :as set] [clojure.set :as set]
[clojure.string :as str] [clojure.string :as str]
[datomic.api :as dc] [datomic.api :as dc]
[malli.core :as mc] [malli.core :as mc]
[malli.util :as mut])) [malli.util :as mut]))
(def query-schema (mc/schema
[:maybe
(into [:map {}
[:vendor {:optional true :default nil} [:maybe [:entity-map {:pull [:db/id :vendor/name]}]]] ]
default-grid-fields-schema)]))
(defn filters [request] (defn filters [request]
[:form {"hx-trigger" "change delay:500ms, keyup changed from:.hot-filter delay:1000ms" [:form {"hx-trigger" "change delay:500ms, keyup changed from:.hot-filter delay:1000ms"
"hx-get" (bidi/path-for ssr-routes/only-routes "hx-get" (bidi/path-for ssr-routes/only-routes
@@ -52,14 +58,14 @@
:url (bidi/path-for ssr-routes/only-routes :url (bidi/path-for ssr-routes/only-routes
:vendor-search) :vendor-search)
:id (str "vendor-search") :id (str "vendor-search")
:value (:vendor (:parsed-query-params request)) :value (:vendor (:query-params request))
:value-fn :db/id :value-fn :db/id
:content-fn :vendor/name})) :content-fn :vendor/name}))
(com/field {:label "Note"} (com/field {:label "Note"}
(com/text-input {:name "note" (com/text-input {:name "note"
:id "note" :id "note"
:class "hot-filter" :class "hot-filter"
:value (:note (:parsed-query-params request)) :value (:note (:query-params request))
:placeholder "HOME DEPOT lte 250.0" :placeholder "HOME DEPOT lte 250.0"
:size :small})) :size :small}))
@@ -67,14 +73,14 @@
(com/text-input {:name "description" (com/text-input {:name "description"
:id "description" :id "description"
:class "hot-filter" :class "hot-filter"
:value (:description (:parsed-query-params request)) :value (:description (:query-params request))
:placeholder "LOWES" :placeholder "LOWES"
:size :small})) :size :small}))
(com/field {:label "Client group"} (com/field {:label "Client group"}
(com/text-input {:name "client-group" (com/text-input {:name "client-group"
:id "client-group" :id "client-group"
:class "hot-filter" :class "hot-filter"
:value (:client-group (:parsed-query-params request)) :value (:client-group (:query-params request))
:placeholder "NTG" :placeholder "NTG"
:size :small}))]]) :size :small}))]])
@@ -100,7 +106,7 @@
:db/id]}]) :db/id]}])
(defn fetch-ids [db request] (defn fetch-ids [db request]
(let [query-params (:parsed-query-params request) (let [query-params (:query-params request)
valid-clients (extract-client-ids (:clients request) valid-clients (extract-client-ids (:clients request)
(:client request) (:client request)
(:client-id query-params) (:client-id query-params)
@@ -179,9 +185,6 @@
:nav com/admin-aside-nav :nav com/admin-aside-nav
:page-specific-nav filters :page-specific-nav filters
:fetch-page fetch-page :fetch-page fetch-page
:parse-query-params (comp
(query-params/parse-key :vendor #(dc/pull (dc/db conn) '[:vendor/name :db/id] (Long/parseLong %)))
(helper/default-parse-query-params grid-page))
:action-buttons (fn [request] :action-buttons (fn [request]
[(com/button {:hx-get (str (bidi/path-for ssr-routes/only-routes ::route/new-dialog)) [(com/button {:hx-get (str (bidi/path-for ssr-routes/only-routes ::route/new-dialog))
:color :primary} :color :primary}
@@ -206,6 +209,7 @@
"Transaction Rules"]] "Transaction Rules"]]
:title "Rules" :title "Rules"
:entity-name "Rule" :entity-name "Rule"
:query-schema query-schema
:route ::route/table :route ::route/table
:headers [{:key "client" :headers [{:key "client"
:name "Client" :name "Client"
@@ -999,5 +1003,10 @@
{}))))}) {}))))})
(fn [h] (fn [h]
(-> h (-> h
(wrap-copy-qp-pqp)
(wrap-apply-sort grid-page)
(wrap-merge-prior-hx)
(wrap-schema-enforce :query-schema query-schema)
(wrap-schema-enforce :hx-schema query-schema)
(wrap-admin) (wrap-admin)
(wrap-client-redirect-unauthenticated))))) (wrap-client-redirect-unauthenticated)))))

View File

@@ -1,38 +1,48 @@
(ns auto-ap.ssr.admin.vendors (ns auto-ap.ssr.admin.vendors
(:require [auto-ap.cursor :as cursor] (:require
[auto-ap.datomic [auto-ap.cursor :as cursor]
:refer [add-sorter-fields apply-pagination apply-sort-3 audit-transact [auto-ap.datomic
audit-transact-batch audit-transact-batch conn merge-query :refer [add-sorter-fields apply-pagination apply-sort-3
pull-attr pull-many query2]] audit-transact audit-transact-batch audit-transact-batch
[auto-ap.datomic.accounts :as d-accounts] conn merge-query pull-attr pull-many query2]]
[auto-ap.logging :as alog] [auto-ap.datomic.accounts :as d-accounts]
[auto-ap.query-params :as query-params] [auto-ap.logging :as alog]
[auto-ap.routes.admin.vendors :as route] [auto-ap.query-params :refer [wrap-copy-qp-pqp]]
[auto-ap.routes.utils [auto-ap.routes.admin.vendors :as route]
[auto-ap.routes.utils
:refer [wrap-admin wrap-client-redirect-unauthenticated]] :refer [wrap-admin wrap-client-redirect-unauthenticated]]
[auto-ap.solr :as solr] [auto-ap.solr :as solr]
[auto-ap.ssr-routes :as ssr-routes] [auto-ap.ssr-routes :as ssr-routes]
[auto-ap.ssr.common-handlers :refer [add-new-entity-handler [auto-ap.ssr.common-handlers :refer [add-new-entity-handler
add-new-primitive-handler]] add-new-primitive-handler]]
[auto-ap.ssr.components :as com] [auto-ap.ssr.components :as com]
[auto-ap.ssr.components.multi-modal :as mm] [auto-ap.ssr.components.multi-modal :as mm]
[auto-ap.ssr.components.timeline :as timeline] [auto-ap.ssr.components.timeline :as timeline]
[auto-ap.ssr.form-cursor :as fc] [auto-ap.ssr.form-cursor :as fc]
[auto-ap.ssr.grid-page-helper :as helper] [auto-ap.ssr.grid-page-helper :as helper :refer [wrap-apply-sort]]
[auto-ap.ssr.hx :as hx] [auto-ap.ssr.hx :as hx]
[auto-ap.ssr.svg :as svg] [auto-ap.ssr.svg :as svg]
[auto-ap.ssr.utils [auto-ap.ssr.utils
:refer [apply-middleware-to-all-handlers entity-id form-validation-error :refer [apply-middleware-to-all-handlers
html-response many-entity modal-response ref->enum-schema default-grid-fields-schema entity-id
ref->select-options strip temp-id wrap-entity wrap-form-4xx-2 form-validation-error html-response many-entity
modal-response ref->enum-schema ref->select-options strip
temp-id wrap-entity wrap-form-4xx-2 wrap-merge-prior-hx
wrap-schema-enforce]] wrap-schema-enforce]]
[bidi.bidi :as bidi] [bidi.bidi :as bidi]
[clojure.string :as str] [clojure.string :as str]
[datomic.api :as dc] [datomic.api :as dc]
[malli.core :as mc] [malli.core :as mc]
[malli.transform :as mt] [malli.transform :as mt]
[malli.util :as mut])) [malli.util :as mut]))
(def query-schema (mc/schema
[:maybe
(into [:map {}
[:name {:optional true :default nil} [:maybe [:string {:string/decode strip}]]]
#_[:role {:optional true} [:maybe (ref->enum-schema "user-role")]]
#_[:client {:optional true :default nil} [:maybe [:entity-map {:pull [:db/id :client/name]}]]] ]
default-grid-fields-schema)]))
(defn filters [request] (defn filters [request]
[:form {"hx-trigger" "change delay:500ms, keyup changed from:.hot-filter delay:1000ms" [:form {"hx-trigger" "change delay:500ms, keyup changed from:.hot-filter delay:1000ms"
"hx-get" (bidi/path-for ssr-routes/only-routes "hx-get" (bidi/path-for ssr-routes/only-routes
@@ -45,13 +55,13 @@
(com/text-input {:name "name" (com/text-input {:name "name"
:id "name" :id "name"
:class "hot-filter" :class "hot-filter"
:value (:name (:parsed-query-params request)) :value (:name (:query-params request))
:placeholder "Cash" :placeholder "Cash"
:size :small})) :size :small}))
(com/field {:label "Type"} (com/field {:label "Type"}
(com/radio-card {:size :small (com/radio-card {:size :small
:name "type" :name "type"
:value (:type (:parsed-query-params request)) :value (:type (:query-params request))
:options [{:value "" :options [{:value ""
:content "All"} :content "All"}
{:value "only-hidden" {:value "only-hidden"
@@ -84,7 +94,7 @@
[:vendor/legal-entity-tin-type :xform iol-ion.query/ident] [:db/ident]}]) [:vendor/legal-entity-tin-type :xform iol-ion.query/ident] [:db/ident]}])
(defn fetch-ids [db request] (defn fetch-ids [db request]
(let [query-params (:parsed-query-params request) (let [query-params (:query-params request)
query (cond-> {:query {:find [] query (cond-> {:query {:find []
:in '[$] :in '[$]
:where '[]} :where '[]}
@@ -139,9 +149,6 @@
:nav com/admin-aside-nav :nav com/admin-aside-nav
:page-specific-nav filters :page-specific-nav filters
:fetch-page fetch-page :fetch-page fetch-page
:parse-query-params (comp
(query-params/parse-key :code query-params/parse-long)
(helper/default-parse-query-params grid-page))
:action-buttons (fn [_] :action-buttons (fn [_]
[(com/button {:hx-get (str (bidi/path-for ssr-routes/only-routes [(com/button {:hx-get (str (bidi/path-for ssr-routes/only-routes
::route/merge)) ::route/merge))
@@ -165,6 +172,7 @@
"Vendors"]] "Vendors"]]
:title "Vendors" :title "Vendors"
:entity-name "Vendor" :entity-name "Vendor"
:query-schema query-schema
:route ::route/table :route ::route/table
:headers [{:key "name" :headers [{:key "name"
:name "Name" :name "Name"
@@ -913,6 +921,11 @@
(fn [cursor _] (account-override-row cursor)))}) (fn [cursor _] (account-override-row cursor)))})
(fn [h] (fn [h]
(-> h (-> h
(wrap-copy-qp-pqp)
(wrap-apply-sort grid-page)
(wrap-merge-prior-hx)
(wrap-schema-enforce :query-schema query-schema)
(wrap-schema-enforce :hx-schema query-schema)
(wrap-admin) (wrap-admin)
(wrap-client-redirect-unauthenticated))))) (wrap-client-redirect-unauthenticated)))))

View File

@@ -2,32 +2,31 @@
(:require (:require
[auto-ap.datomic :refer [apply-pagination-raw conn]] [auto-ap.datomic :refer [apply-pagination-raw conn]]
[auto-ap.graphql.utils :refer [assert-can-see-client]] [auto-ap.graphql.utils :refer [assert-can-see-client]]
[auto-ap.query-params :refer [wrap-copy-qp-pqp]]
[auto-ap.routes.utils [auto-ap.routes.utils
:refer [wrap-client-redirect-unauthenticated wrap-secure]] :refer [wrap-client-redirect-unauthenticated wrap-secure]]
[auto-ap.ssr-routes :as ssr-routes] [auto-ap.ssr-routes :as ssr-routes]
[auto-ap.ssr.components :as com] [auto-ap.ssr.components :as com]
[auto-ap.ssr.form-cursor :as fc] [auto-ap.ssr.form-cursor :as fc]
[auto-ap.ssr.grid-page-helper :as helper] [auto-ap.ssr.grid-page-helper :as helper :refer [wrap-apply-sort]]
[auto-ap.ssr.nested-form-params :refer [wrap-nested-form-params]] [auto-ap.ssr.nested-form-params :refer [wrap-nested-form-params]]
[auto-ap.ssr.svg :as svg] [auto-ap.ssr.svg :as svg]
[auto-ap.ssr.utils [auto-ap.ssr.utils
:refer [apply-middleware-to-all-handlers :refer [apply-middleware-to-all-handlers default-grid-fields-schema
entity-id entity-id html-response main-transformer modal-response
html-response ref->enum-schema ref->select-options strip wrap-entity
main-transformer wrap-form-4xx-2 wrap-merge-prior-hx wrap-schema-enforce]]
modal-response
ref->enum-schema
ref->select-options
strip
wrap-entity
wrap-form-4xx-2
wrap-schema-enforce]]
[bidi.bidi :as bidi] [bidi.bidi :as bidi]
[clojure.string :as str] [clojure.string :as str]
[datomic.api :as dc] [datomic.api :as dc]
[hiccup.util :refer [url]] [hiccup.util :refer [url]]
[malli.core :as mc])) [malli.core :as mc]))
(def query-schema (mc/schema
[:maybe
(into [:map {} ]
default-grid-fields-schema)]))
(def vendor-read '[:db/id (def vendor-read '[:db/id
:vendor/name :vendor/name
{:vendor/legal-entity-1099-type [:db/ident]} {:vendor/legal-entity-1099-type [:db/ident]}
@@ -59,7 +58,7 @@
client-id client-id
vendor-id))) vendor-id)))
(defn fetch-page [{:keys [trimmed-clients parsed-query-params] :as request user :identity}] (defn fetch-page [{:keys [trimmed-clients query-params] :as request user :identity}]
(let [results (dc/q '[:find (let [results (dc/q '[:find
(pull ?c [:client/code :db/id]) (pull ?c [:client/code :db/id])
(pull ?v vendor-read) (pull ?v vendor-read)
@@ -83,8 +82,8 @@
(sort-by (fn [[client _ amount]] (sort-by (fn [[client _ amount]]
[(:client/code client ) amount])) [(:client/code client ) amount]))
(into [])) (into []))
paginated (apply-pagination-raw {:start (:start parsed-query-params) paginated (apply-pagination-raw {:start (:start query-params)
:per-page (:per-page parsed-query-params)} all)] :per-page (:per-page query-params)} all)]
[(:entries paginated) (:count paginated)])) [(:entries paginated) (:count paginated)]))
(def grid-page (def grid-page
@@ -102,6 +101,7 @@
"1099 Vendor Info"]] "1099 Vendor Info"]]
:title "1099 Vendors" :title "1099 Vendors"
:entity-name "Vendors" :entity-name "Vendors"
:query-schema query-schema
:route :company-1099-vendor-table :route :company-1099-vendor-table
:row-buttons (fn [request e] :row-buttons (fn [request e]
[(com/icon-button {:hx-get (url (bidi/path-for ssr-routes/only-routes [(com/icon-button {:hx-get (url (bidi/path-for ssr-routes/only-routes
@@ -358,27 +358,31 @@
(def page (helper/page-route grid-page)) (def page (helper/page-route grid-page))
(def key->handler (def key->handler
(apply-middleware-to-all-handlers (apply-middleware-to-all-handlers
(->> (->>
{ {:company-1099 page
:company-1099 page :company-1099-vendor-table vendor-table
:company-1099-vendor-table vendor-table :company-1099-vendor-dialog (-> vendor-dialog
:company-1099-vendor-dialog (-> vendor-dialog (wrap-entity [:route-params :vendor-id] default-vendor-read)
(wrap-entity [:route-params :vendor-id] default-vendor-read) (wrap-schema-enforce :route-schema [:map [:vendor-id entity-id]]
(wrap-schema-enforce :route-schema [:map [:vendor-id entity-id]] :query-schema [:map [:client-id entity-id]]))
:query-schema [:map [:client-id entity-id]])) :company-1099-vendor-save (-> vendor-save
:company-1099-vendor-save (-> vendor-save (wrap-entity [:form-params :db/id] default-vendor-read)
(wrap-entity [:form-params :db/id] default-vendor-read) (wrap-schema-enforce :form-schema form-schema
(wrap-schema-enforce :form-schema form-schema :route-schema [:map [:vendor-id entity-id]]
:route-schema [:map [:vendor-id entity-id]] :query-schema [:map [:client-id entity-id]])
:query-schema [:map [:client-id entity-id]]) (wrap-nested-form-params)
(wrap-nested-form-params) (wrap-form-4xx-2 (-> vendor-dialog
(wrap-form-4xx-2 (-> vendor-dialog (wrap-entity [:form-params :db/id] default-vendor-read)
(wrap-entity [:form-params :db/id] default-vendor-read) (wrap-entity [:route-params :vendor-id] default-vendor-read)
(wrap-entity [:route-params :vendor-id] default-vendor-read) (wrap-schema-enforce :route-schema [:map [:vendor-id entity-id]]
(wrap-schema-enforce :route-schema [:map [:vendor-id entity-id]] :query-schema [:map [:client-id entity-id]]))))})
:query-schema [:map [:client-id entity-id]]))))}) (fn [h]
(fn [h] (-> h
(-> h (wrap-copy-qp-pqp)
(wrap-secure) (wrap-apply-sort grid-page)
(wrap-client-redirect-unauthenticated))))) (wrap-merge-prior-hx)
(wrap-schema-enforce :query-schema query-schema)
(wrap-schema-enforce :hx-schema query-schema)
(wrap-secure)
(wrap-client-redirect-unauthenticated)))))

View File

@@ -1,23 +1,33 @@
(ns auto-ap.ssr.company.plaid (ns auto-ap.ssr.company.plaid
(:require [auto-ap.datomic (:require
[auto-ap.datomic
:refer [add-sorter-fields apply-pagination apply-sort-3 conn merge-query :refer [add-sorter-fields apply-pagination apply-sort-3 conn merge-query
pull-attr pull-many-by-id query2]] pull-attr pull-many-by-id query2]]
[auto-ap.graphql.utils :refer [assert-can-see-client]] [auto-ap.graphql.utils :refer [assert-can-see-client]]
[auto-ap.logging :as alog] [auto-ap.logging :as alog]
[auto-ap.plaid.core :as p] [auto-ap.plaid.core :as p]
[auto-ap.ssr-routes :as ssr-routes] [auto-ap.query-params :refer [wrap-copy-qp-pqp]]
[auto-ap.ssr.components :as com] [auto-ap.routes.utils :refer [wrap-client-redirect-unauthenticated
[auto-ap.ssr.grid-page-helper :as helper] wrap-secure]]
[auto-ap.ssr.hx :as hx] [auto-ap.ssr-routes :as ssr-routes]
[auto-ap.ssr.svg :as svg] [auto-ap.ssr.components :as com]
[auto-ap.ssr.utils :refer [html-response]] [auto-ap.ssr.grid-page-helper :as helper :refer [wrap-apply-sort]]
[auto-ap.time :as atime] [auto-ap.ssr.svg :as svg]
[bidi.bidi :as bidi] [auto-ap.ssr.utils :refer [apply-middleware-to-all-handlers
[clj-time.coerce :as coerce] default-grid-fields-schema html-response
[clj-time.core :as time] wrap-merge-prior-hx wrap-schema-enforce]]
[clojure.string :as str] [auto-ap.time :as atime]
[datomic.api :as dc] [bidi.bidi :as bidi]
[hiccup2.core :as hiccup])) [clj-time.coerce :as coerce]
[clj-time.core :as time]
[clojure.string :as str]
[datomic.api :as dc]
[hiccup2.core :as hiccup]
[malli.core :as mc]))
(def query-schema (mc/schema
[:maybe
(into [:map {} ]
default-grid-fields-schema)]))
(def default-read '[:db/id (def default-read '[:db/id
:plaid-item/external-id :plaid-item/external-id
@@ -37,21 +47,21 @@
:plaid-account/name]}]) :plaid-account/name]}])
(defn fetch-ids [db request] (defn fetch-ids [db request]
(let [query-params (:parsed-query-params request) (let [query-params (:query-params request)
query (cond-> {:query {:find [] query (cond-> {:query {:find []
:in ['$ '[?xx ...]] :in ['$ '[?xx ...]]
:where ['[?e :plaid-item/client ?xx]]} :where ['[?e :plaid-item/client ?xx]]}
:args [db (:trimmed-clients request)]} :args [db (:trimmed-clients request)]}
(:sort query-params) (add-sorter-fields {"external-id" ['[?e :plaid-item/external-id ?sort-external-id]] (:sort query-params) (add-sorter-fields {"external-id" ['[?e :plaid-item/external-id ?sort-external-id]]
"status" ['[?e :plaid-item/status ?sort-status]]} "plaid-bank-status" ['[?e :plaid-item/status ?sort-plaid-bank-status]]
query-params) "status" ['[?e :plaid-item/status ?sort-status]]}
query-params)
true true
(merge-query {:query {:find ['?e] (merge-query {:query {:find ['?e]
:where ['[?e :plaid-item/external-id]]}}))] :where ['[?e :plaid-item/external-id]]}}))]
(clojure.pprint/pprint query-params)
(cond->> (query2 query) (cond->> (query2 query)
true (apply-sort-3 query-params) true (apply-sort-3 query-params)
true (apply-pagination query-params)))) true (apply-pagination query-params))))
@@ -145,6 +155,7 @@
"Plaid"]] "Plaid"]]
:title "Plaid Accounts" :title "Plaid Accounts"
:entity-name "Plaid accounts" :entity-name "Plaid accounts"
:query-schema query-schema
:route :company-plaid-table :route :company-plaid-table
:action-buttons (fn [request] :action-buttons (fn [request]
(when-let [client-code (:client/code (:client request))] (when-let [client-code (:client/code (:client request))]
@@ -172,7 +183,6 @@
:render :plaid-item/external-id} :render :plaid-item/external-id}
{:key "integreat-plaid-status" {:key "integreat-plaid-status"
:name "Integreat ↔ Plaid status" :name "Integreat ↔ Plaid status"
:sort-key "integreat-plaid-status"
:render (fn [e] :render (fn [e]
(let [bad-integration (->> (:plaid-item/accounts e) (let [bad-integration (->> (:plaid-item/accounts e)
@@ -229,3 +239,21 @@
(def page (helper/page-route grid-page)) (def page (helper/page-route grid-page))
(def table (helper/table-route grid-page)) (def table (helper/table-route grid-page))
(def key->handler
(apply-middleware-to-all-handlers
{
:company-plaid page
:company-plaid-table table
:company-plaid-link link
:company-plaid-relink relink
}
(fn [h]
(-> h
(wrap-copy-qp-pqp)
(wrap-apply-sort grid-page)
(wrap-merge-prior-hx)
(wrap-schema-enforce :query-schema query-schema)
(wrap-schema-enforce :hx-schema query-schema)
(wrap-client-redirect-unauthenticated)
(wrap-secure)))))

View File

@@ -1,30 +1,45 @@
(ns auto-ap.ssr.company.reports (ns auto-ap.ssr.company.reports
(:require [amazonica.aws.s3 :as s3] (:require
[auto-ap.datomic [amazonica.aws.s3 :as s3]
[auto-ap.datomic
:refer [add-sorter-fields apply-pagination apply-sort-3 conn merge-query :refer [add-sorter-fields apply-pagination apply-sort-3 conn merge-query
pull-many query2]] pull-many query2]]
[auto-ap.graphql.utils :refer [assert-can-see-client is-admin?]] [auto-ap.graphql.utils :refer [assert-can-see-client is-admin?]]
[auto-ap.routes.utils :refer [wrap-client-redirect-unauthenticated [auto-ap.query-params :refer [wrap-copy-qp-pqp]]
wrap-secure]] [auto-ap.routes.utils :refer [wrap-client-redirect-unauthenticated
[auto-ap.ssr-routes :as ssr-routes] wrap-secure]]
[auto-ap.ssr.company.reports.expense :as company-expense-report] [auto-ap.ssr-routes :as ssr-routes]
[auto-ap.ssr.company.reports.reconciliation :as company-reconciliation-report] [auto-ap.ssr.company.reports.expense :as company-expense-report]
[auto-ap.ssr.components :as com] [auto-ap.ssr.company.reports.reconciliation :as company-reconciliation-report]
[auto-ap.ssr.grid-page-helper :as helper] [auto-ap.ssr.components :as com]
[auto-ap.ssr.svg :as svg] [auto-ap.ssr.grid-page-helper :as helper :refer [wrap-apply-sort]]
[auto-ap.ssr.utils :refer [apply-middleware-to-all-handlers [auto-ap.ssr.svg :as svg]
html-response]] [auto-ap.ssr.utils :refer [apply-middleware-to-all-handlers clj-date-schema
[auto-ap.time :as atime] default-grid-fields-schema html-response
[bidi.bidi :as bidi] wrap-merge-prior-hx wrap-schema-enforce]]
[clojure.set :as set] [auto-ap.time :as atime]
[config.core :refer [env]] [bidi.bidi :as bidi]
[datomic.api :as dc])) [clojure.set :as set]
[config.core :refer [env]]
[datomic.api :as dc]
[malli.core :as mc]))
(def query-schema (mc/schema
[:maybe
(into [:map {:date-range [:date-range :start-date :end-date]}
[:start-date {:optional true}
[:maybe clj-date-schema]]
[:end-date {:optional true}
[:maybe clj-date-schema]]
[:client {:optional true :default nil} [:maybe [:entity-map {:pull [:db/id :client/name]}]]]
]
default-grid-fields-schema)]))
(def default-read '[:db/id :report/client [:report/created :xform clj-time.coerce/from-date] :report/url :report/name :report/creator]) (def default-read '[:db/id :report/client [:report/created :xform clj-time.coerce/from-date] :report/url :report/name :report/creator])
(defn fetch-ids [db request] (defn fetch-ids [db request]
(let [query-params (:parsed-query-params request) (let [query-params (:query-params request)
query (cond-> {:query {:find [] query (cond-> {:query {:find []
:in '[$ [?c ...]] :in '[$ [?c ...]]
:where '[[?e :report/client ?c]]} :where '[[?e :report/client ?c]]}
@@ -80,6 +95,7 @@
"Reports"]] "Reports"]]
:title "Reports" :title "Reports"
:entity-name "Reports" :entity-name "Reports"
:query-schema query-schema
:route :company-reports-table :route :company-reports-table
:row-buttons (fn [request e] :row-buttons (fn [request e]
[(com/a-icon-button {:href (:report/url e)} [(com/a-icon-button {:href (:report/url e)}
@@ -143,5 +159,10 @@
(into company-reconciliation-report/key->handler)) (into company-reconciliation-report/key->handler))
(fn [h] (fn [h]
(-> h (-> h
(wrap-copy-qp-pqp)
(wrap-apply-sort grid-page)
(wrap-merge-prior-hx)
(wrap-schema-enforce :query-schema query-schema)
(wrap-schema-enforce :hx-schema query-schema)
(wrap-secure) (wrap-secure)
(wrap-client-redirect-unauthenticated))))) (wrap-client-redirect-unauthenticated)))))

View File

@@ -1,19 +1,28 @@
(ns auto-ap.ssr.company.yodlee (ns auto-ap.ssr.company.yodlee
(:require [auto-ap.datomic (:require
[auto-ap.datomic
:refer [add-sorter-fields apply-pagination apply-sort-3 conn merge-query :refer [add-sorter-fields apply-pagination apply-sort-3 conn merge-query
pull-attr pull-many query2]] pull-attr pull-many query2]]
[auto-ap.graphql.utils :refer [assert-can-see-client is-admin?]] [auto-ap.graphql.utils :refer [assert-can-see-client is-admin?]]
[auto-ap.ssr-routes :as ssr-routes] [auto-ap.permissions :refer [wrap-must]]
[auto-ap.ssr.components :as com] [auto-ap.query-params :refer [wrap-copy-qp-pqp]]
[auto-ap.ssr.grid-page-helper :as helper] [auto-ap.routes.utils :refer [wrap-client-redirect-unauthenticated
[auto-ap.ssr.svg :as svg] wrap-secure]]
[auto-ap.ssr.utils :refer [html-response modal-response]] [auto-ap.ssr-routes :as ssr-routes]
[auto-ap.time :as atime] [auto-ap.ssr.components :as com]
[auto-ap.yodlee.core2 :as yodlee] [auto-ap.ssr.grid-page-helper :as helper :refer [wrap-apply-sort]]
[bidi.bidi :as bidi] [auto-ap.ssr.svg :as svg]
[config.core :refer [env]] [auto-ap.ssr.utils :refer [apply-middleware-to-all-handlers
[datomic.api :as dc] default-grid-fields-schema entity-id
[hiccup2.core :as hiccup])) html-response modal-response wrap-merge-prior-hx
wrap-schema-enforce]]
[auto-ap.time :as atime]
[auto-ap.yodlee.core2 :as yodlee]
[bidi.bidi :as bidi]
[config.core :refer [env]]
[datomic.api :as dc]
[hiccup2.core :as hiccup]
[malli.core :as mc]))
(def default-read '[:db/id (def default-read '[:db/id
[:yodlee-provider-account/last-updated :xform clj-time.coerce/from-date] [:yodlee-provider-account/last-updated :xform clj-time.coerce/from-date]
@@ -23,11 +32,15 @@
{:yodlee-provider-account/accounts [:yodlee-account/name :yodlee-account/number] {:yodlee-provider-account/accounts [:yodlee-account/name :yodlee-account/number]
:yodlee-provider-account/client [:client/code]}]) :yodlee-provider-account/client [:client/code]}])
(def query-schema (mc/schema
[:maybe
(into [:map {}
[:client-id {:optional true} [:maybe entity-id]] ]
default-grid-fields-schema)]))
(defn fetch-ids [db request] (defn fetch-ids [db request]
(let [query-params (:parsed-query-params request)] (let [query-params (:query-params request)
(->> (cond-> {:query {:find [] query (cond-> {:query {:find []
:in ['$ '[?xx ...]] :in ['$ '[?xx ...]]
:where ['[?e :yodlee-provider-account/id] :where ['[?e :yodlee-provider-account/id]
'[?e :yodlee-provider-account/client ?xx]]} '[?e :yodlee-provider-account/client ?xx]]}
@@ -35,11 +48,15 @@
(:sort query-params) (add-sorter-fields {"status" ['[?e :yodlee-provider-account/status ?sort-status]] (:sort query-params) (add-sorter-fields {"status" ['[?e :yodlee-provider-account/status ?sort-status]]
"last-updated" ['[?e :yodlee-provider-account/last-updated ?sort-last-updated]]} "client" ['[?e :yodlee-provider-account/client ?c]
'[?c :client/code ?sort-client]]
"provider-account" ['[?e :yodlee-provider-account/id ?sort-provider-account]]
"last-updated" ['[?e :yodlee-provider-account/last-updated ?sort-last-updated]]}
query-params) query-params)
true true
(merge-query {:query {:find ['?e ] (merge-query {:query {:find ['?e ]
:where ['[?e :yodlee-provider-account/id]]}})) :where ['[?e :yodlee-provider-account/id]]}}))]
(->> query
(query2) (query2)
(apply-sort-3 query-params) (apply-sort-3 query-params)
@@ -133,6 +150,7 @@ fastlink.open({fastLinkURL: '%s',
"Yodlee"]] "Yodlee"]]
:title "Yodlee Accounts" :title "Yodlee Accounts"
:entity-name "Yodlee accounts" :entity-name "Yodlee accounts"
:query-schema query-schema
:route :company-yodlee-table :route :company-yodlee-table
:action-buttons (fn [request] :action-buttons (fn [request]
[[:div.flex.flex-col.flex-shrink [[:div.flex.flex-col.flex-shrink
@@ -211,3 +229,21 @@ fastlink.open({fastLinkURL: '%s',
identity identity
provider-account provider-account
{:flash? true})))) {:flash? true}))))
(def key->handler
(apply-middleware-to-all-handlers
{
:company-yodlee page
:company-yodlee-table table
:company-yodlee-fastlink-dialog fastlink-dialog
}
(fn [h]
(-> h
(wrap-copy-qp-pqp)
(wrap-apply-sort grid-page)
(wrap-merge-prior-hx)
(wrap-schema-enforce :query-schema query-schema)
(wrap-schema-enforce :hx-schema query-schema)
(wrap-client-redirect-unauthenticated)
(wrap-secure)))))

View File

@@ -210,7 +210,7 @@
(menu-button- {:href (str (bidi/path-for ssr-routes/only-routes (menu-button- {:href (str (bidi/path-for ssr-routes/only-routes
:pos-cash-drawer-shifts) :pos-cash-drawer-shifts)
"?date-range=week") "?date-range=week")
:active? (= :cash-drawer-shifts (:matched-route request)) :active? (= :pos-cash-drawer-shifts (:matched-route request))
:hx-boost "true"} :hx-boost "true"}
"Cash drawer shifts")))) "Cash drawer shifts"))))

View File

@@ -61,15 +61,8 @@
:not-found not-found/page :not-found not-found/page
:company (wrap-client-redirect-unauthenticated (wrap-secure company/page)) :company (wrap-client-redirect-unauthenticated (wrap-secure company/page))
:company-plaid (wrap-client-redirect-unauthenticated (wrap-secure company-plaid/page))
:company-plaid-table (wrap-client-redirect-unauthenticated (wrap-secure company-plaid/table))
:company-plaid-link (wrap-client-redirect-unauthenticated (wrap-secure company-plaid/link))
:company-plaid-relink (wrap-client-redirect-unauthenticated (wrap-secure company-plaid/relink))
:company-update-signature (wrap-client-redirect-unauthenticated (wrap-secure company/upload-signature-data)) :company-update-signature (wrap-client-redirect-unauthenticated (wrap-secure company/upload-signature-data))
:company-upload-signature (wrap-client-redirect-unauthenticated (wrap-secure company/upload-signature-file)) :company-upload-signature (wrap-client-redirect-unauthenticated (wrap-secure company/upload-signature-file))
:company-yodlee (wrap-client-redirect-unauthenticated (wrap-secure company-yodlee/page))
:company-yodlee-table (wrap-client-redirect-unauthenticated (wrap-secure company-yodlee/table))
:company-yodlee-fastlink-dialog (wrap-client-redirect-unauthenticated (wrap-secure company-yodlee/fastlink-dialog))
:company-yodlee-provider-account-refresh (wrap-client-redirect-unauthenticated (wrap-admin company-yodlee/refresh-provider-account)) :company-yodlee-provider-account-refresh (wrap-client-redirect-unauthenticated (wrap-admin company-yodlee/refresh-provider-account))
:company-yodlee-provider-account-reauthenticate (wrap-client-redirect-unauthenticated (wrap-secure company-yodlee/reauthenticate)) :company-yodlee-provider-account-reauthenticate (wrap-client-redirect-unauthenticated (wrap-secure company-yodlee/reauthenticate))
:invoice-glimpse (wrap-client-redirect-unauthenticated (wrap-must (wrap-secure invoice-glimpse/page) {:activity :import :subject :invoice})) :invoice-glimpse (wrap-client-redirect-unauthenticated (wrap-must (wrap-secure invoice-glimpse/page) {:activity :import :subject :invoice}))
@@ -86,7 +79,9 @@
:transaction-insight-explain (wrap-client-redirect-unauthenticated (wrap-admin insights/explain)) :transaction-insight-explain (wrap-client-redirect-unauthenticated (wrap-admin insights/explain))
:admin-ezcater-xls (wrap-client-redirect-unauthenticated (wrap-admin ezcater-xls/page)) :admin-ezcater-xls (wrap-client-redirect-unauthenticated (wrap-admin ezcater-xls/page))
:search (wrap-client-redirect-unauthenticated (wrap-secure search/dialog-contents))} :search (wrap-client-redirect-unauthenticated (wrap-secure search/dialog-contents))}
(into company-plaid/key->handler)
(into company-reports/key->handler) (into company-reports/key->handler)
(into company-yodlee/key->handler)
(into company-1099/key->handler) (into company-1099/key->handler)
(into invoice/key->handler) (into invoice/key->handler)
(into import-batch/key->handler) (into import-batch/key->handler)

View File

@@ -206,49 +206,6 @@
(defn default-unparse-query-params [query-params]
(reduce
(fn [query-params [k value]]
(assoc query-params k
(cond (= k :sort)
(sort->query value)
(instance? org.joda.time.base.AbstractInstant value)
(atime/unparse-local value atime/normal-date)
(instance? Long value)
(str value)
(instance? Double value)
(format "%.2f" value)
(instance? Float value)
(format "%.2f" value)
(keyword? value)
(name value)
(and (map? value)
(:db/id value))
(:db/id value)
:else
value)))
query-params
query-params))
(defn default-parse-query-params [grid-spec]
(comp
(query-params/apply-remove-sort)
(query-params/apply-toggle-sort grid-spec)
(query-params/apply-date-range :date-range :start-date :end-date)
(query-params/parse-key :exact-match-id query-params/parse-long)
(query-params/parse-key :sort #(query-params/parse-sort grid-spec %))
(query-params/parse-key :per-page query-params/parse-long)
(query-params/parse-key :start query-params/parse-long)
(query-params/parse-key :start-date query-params/parse-date)
(query-params/parse-key :end-date query-params/parse-date)))
(defn wrap-trim-client-ids [handler] (defn wrap-trim-client-ids [handler]
(fn trim-client-ids [request] (fn trim-client-ids [request]
(let [valid-clients (extract-client-ids (:clients request) (let [valid-clients (extract-client-ids (:clients request)
@@ -262,36 +219,30 @@
(handler (assoc request :trimmed-clients valid-clients))))) (handler (assoc request :trimmed-clients valid-clients)))))
(defn table-route [grid-spec & {:keys [parse-query-params? push-url?] :or {parse-query-params? true push-url? true}}] (defn table-route [grid-spec & {:keys [push-url?] :or { push-url? true}}]
(cond-> (fn table [{:keys [identity] :as request}] (cond-> (fn table [{:keys [identity] :as request}]
(println "SORT IS") (html-response (table*
(clojure.pprint/pprint (sort->query (:sort (:query-params request)))) grid-spec
(let [unparse-query-params (or (:unparse-query grid-spec) identity
default-unparse-query-params)] request)
(html-response (table* :headers (when push-url?
grid-spec {"hx-push-url" (str "?" (url/map->query
identity (dissoc (if (:query-schema grid-spec)
request) (update (filter-vals #(not (nil? %))
:headers (when push-url? (m/encode (:query-schema grid-spec)
{"hx-push-url" (str "?" (url/map->query (:query-params request)
(dissoc (if (:query-schema grid-spec) main-transformer))
(update (filter-vals #(not (nil? %)) "sort" sort->query)
(m/encode (:query-schema grid-spec) {})
(:query-params request) "selected" "all-selected")))}) ;; TODO seems hacky to special case selected and all-selected here
main-transformer)) :oob (when-let [oob-render (:oob-render grid-spec)]
"sort" sort->query) (oob-render request))))
(unparse-query-params (:parsed-query-params request))) true (wrap-trim-client-ids)
"selected" "all-selected")))}) ;; TODO seems hacky to special case selected and all-selected here true (wrap-secure)
:oob (when-let [oob-render (:oob-render grid-spec)] true (wrap-client-redirect-unauthenticated)))
(oob-render request)))))
true (wrap-trim-client-ids)
parse-query-params? (query-params/wrap-parse-query-params (or (:parse-query-params grid-spec)
(default-parse-query-params grid-spec)))
true (wrap-secure)
true (wrap-client-redirect-unauthenticated)))
(defn csv-route [{:keys [fetch-page headers page->csv-entities]} & {:keys [parse-query-params?] :or {parse-query-params? true}}] (defn csv-route [{:keys [fetch-page headers page->csv-entities]} & {:keys []}]
(cond-> (fn csv-route [{:keys [identity] :as request}] (cond-> (fn csv-route [{:keys [identity] :as request}]
(let [page-results (fetch-page (assoc-in request [:query-params :per-page] Long/MAX_VALUE)) (let [page-results (fetch-page (assoc-in request [:query-params :per-page] Long/MAX_VALUE))
@@ -314,7 +265,7 @@
true (wrap-secure) true (wrap-secure)
true (wrap-client-redirect-unauthenticated))) true (wrap-client-redirect-unauthenticated)))
(defn page-route [grid-spec & {:keys [parse-query-params?] :or {parse-query-params? true}}] (defn page-route [grid-spec & {:keys []}]
(cond-> (fn page [{:keys [identity] :as request}] (cond-> (fn page [{:keys [identity] :as request}]
(alog/info ::page-route (alog/info ::page-route
:pqp (:parsed-query-params request) :pqp (:parsed-query-params request)
@@ -346,8 +297,6 @@
(:title grid-spec) (:title grid-spec)
((:title grid-spec) request)))) ((:title grid-spec) request))))
true (wrap-trim-client-ids) true (wrap-trim-client-ids)
parse-query-params? (query-params/wrap-parse-query-params (or (:parse-query-params grid-spec)
(default-parse-query-params grid-spec)))
true (wrap-secure) true (wrap-secure)
true (wrap-client-redirect-unauthenticated))) true (wrap-client-redirect-unauthenticated)))
@@ -376,14 +325,10 @@
[:=> [:=>
[:cat map?] [:cat map?]
nat-int?]] nat-int?]]
[:query-schema :any]
[:fetch-page [:=> [:fetch-page [:=>
[:cat request-spec] [:cat request-spec]
[:cat [:vector entity-spec] :int]]] [:cat [:vector entity-spec] :int]]]
[:parse-query-params
{:optional true}
[:=>
[:cat [:map-of :keyword :any]]
[:map-of :keyword :any]]]
[:above-grid [:above-grid
{:optional true {:optional true
:default (fn [request])} :default (fn [request])}

View File

@@ -438,8 +438,6 @@
[(assoc-in (date-range-field* request) [1 :hx-swap-oob] true) [(assoc-in (date-range-field* request) [1 :hx-swap-oob] true)
(assoc-in (exact-match-id* request) [1 :hx-swap-oob] true)]) (assoc-in (exact-match-id* request) [1 :hx-swap-oob] true)])
:query-schema query-schema :query-schema query-schema
:parse-query-params (fn [p]
(mc/decode query-schema p main-transformer))
:action-buttons (fn [request] :action-buttons (fn [request]
(let [[_ _ outstanding total] (:page-results request)] (let [[_ _ outstanding total] (:page-results request)]
[ [
@@ -816,10 +814,10 @@
(apply-middleware-to-all-handlers (apply-middleware-to-all-handlers
{::route/import-page {::route/import-page
(-> (->
(helper/page-route grid-page :parse-query-params? false) (helper/page-route grid-page)
(wrap-implied-route-param :status nil)) (wrap-implied-route-param :status nil))
::route/import-table ::route/import-table
(-> (helper/table-route grid-page :parse-query-params? false) (-> (helper/table-route grid-page)
(wrap-implied-route-param :status nil)) (wrap-implied-route-param :status nil))
::route/disapprove (-> disapprove ::route/disapprove (-> disapprove

View File

@@ -1275,13 +1275,13 @@
(def key->handler (def key->handler
(apply-middleware-to-all-handlers (apply-middleware-to-all-handlers
(-> (->
{::route/all-page (-> (helper/page-route grid-page :parse-query-params? false) {::route/all-page (-> (helper/page-route grid-page)
(wrap-implied-route-param :status nil)) (wrap-implied-route-param :status nil))
::route/paid-page (-> (helper/page-route grid-page :parse-query-params? false) ::route/paid-page (-> (helper/page-route grid-page)
(wrap-implied-route-param :status :invoice-status/paid)) (wrap-implied-route-param :status :invoice-status/paid))
::route/unpaid-page (-> (helper/page-route grid-page :parse-query-params? false) ::route/unpaid-page (-> (helper/page-route grid-page)
(wrap-implied-route-param :status :invoice-status/unpaid)) (wrap-implied-route-param :status :invoice-status/unpaid))
::route/voided-page (-> (helper/page-route grid-page :parse-query-params? false) ::route/voided-page (-> (helper/page-route grid-page)
(wrap-implied-route-param :status :invoice-status/voided)) (wrap-implied-route-param :status :invoice-status/voided))
::route/legacy-invoices (redirect-handler ::route/all-page) ::route/legacy-invoices (redirect-handler ::route/all-page)
::route/legacy-import-invoices (redirect-handler ::route/import-page) ::route/legacy-import-invoices (redirect-handler ::route/import-page)

View File

@@ -131,7 +131,7 @@
[:div {:x-data (hx/json { "showTable" false})} [:div {:x-data (hx/json { "showTable" false})}
[:form {:hx-post (bidi.bidi/path-for ssr-routes/only-routes ::route/external-import-import) [:form {:hx-post (bidi.bidi/path-for ssr-routes/only-routes ::route/external-import-import)
:autocomplete "off" } :autocomplete "off"}
(when (:just-parsed? request) (when (:just-parsed? request)
[:div (hx/htmx-transition-appear {:class "bg-green-50 text-green-700 rounded p-4 m-2 max-w-screen-2xl"}) [:div (hx/htmx-transition-appear {:class "bg-green-50 text-green-700 rounded p-4 m-2 max-w-screen-2xl"})
(format "Your data has been parsed. %,d rows found." (count (fc/field-value)))]) (format "Your data has been parsed. %,d rows found." (count (fc/field-value)))])
@@ -237,20 +237,20 @@
(com/button {:color :primary} "Import")])]]])))]) (com/button {:color :primary} "Import")])]]])))])
(defn external-import-text-form* [request] (defn external-import-text-form* [request]
(fc/start-form (fc/start-form
(or (:form-params request) {}) (:form-errors request) (or (:form-params request) {}) (:form-errors request)
[:form#parse-form {:x-data (hx/json {"clipboard" nil}) [:form#parse-form {:x-data (hx/json {"clipboard" nil})
:hx-post (bidi.bidi/path-for ssr-routes/only-routes ::route/external-import-parse) :hx-post (bidi.bidi/path-for ssr-routes/only-routes ::route/external-import-parse)
:hx-swap "outerHTML" :hx-swap "outerHTML"
:hx-trigger "pasted"} :hx-trigger "pasted"}
(fc/with-field :table (fc/with-field :table
[:div [:div
(com/errors {:errors (fc/field-errors)} ) (com/errors {:errors (fc/field-errors)})
(com/text-area {:x-model "clipboard" :name (fc/field-name) :value (fc/field-value) :class "hidden"})]) (com/text-area {:x-model "clipboard" :name (fc/field-name) :value (fc/field-value) :class "hidden"})])
(com/button {"@click.prevent" "clipboard = (await getclpboard()); $nextTick(() => $dispatch('pasted'))" (com/button {"@click.prevent" "clipboard = (await getclpboard()); $nextTick(() => $dispatch('pasted'))"
"x-on:paste.document" "clipboard = (await getclpboard()); console.log(clipboard); $nextTick(() => $dispatch('pasted'))" } "x-on:paste.document" "clipboard = (await getclpboard()); console.log(clipboard); $nextTick(() => $dispatch('pasted'))"}
"Load from clipboard")]) "Load from clipboard")]))
)
(defn external-import-form* [request] (defn external-import-form* [request]
[:div#forms {:hx-target "this" [:div#forms {:hx-target "this"
:hx-swap "outerHTML"} :hx-swap "outerHTML"}
@@ -291,8 +291,8 @@
var r = await c[0].getType('text/plain') var r = await c[0].getType('text/plain')
console.log(r) console.log(r)
return await r.text() return await r.text()
}") }")]
]
(external-import-form* request) (external-import-form* request)
[:div #_{:x-data (hx/json {:selected [] :all_selected false :type (:entity-name grid-spec)}) [:div #_{:x-data (hx/json {:selected [] :all_selected false :type (:entity-name grid-spec)})
"x-on:copy" "if (selected.length > 0) {$clipboard(JSON.stringify({'type': type, 'selected': selected}))}" "x-on:copy" "if (selected.length > 0) {$clipboard(JSON.stringify({'type': type, 'selected': selected}))}"
@@ -307,14 +307,14 @@
"External Ledger Import" "External Ledger Import"
#_(if (string? (:title grid-spec)) #_(if (string? (:title grid-spec))
(:title grid-spec) (:title grid-spec)
((:title grid-spec) request))) ((:title grid-spec) request))))
)
(defn trim-header [t] (defn trim-header [t]
(if (->> t (if (->> t
first first
(map clojure.string/lower-case ) (map clojure.string/lower-case)
(filter #{"id" "client" "source" "vendor" "date" "account" "location" "debit"}) (filter #{"id" "client" "source" "vendor" "date" "account" "location" "debit"})
seq) seq)
(drop 1 t) (drop 1 t)
@@ -336,34 +336,34 @@
(def parse-form-schema (mc/schema (def parse-form-schema (mc/schema
[:map [:map
[:table {:min 1 :error/message "Clipboard should contain rows to import" [:table {:min 1 :error/message "Clipboard should contain rows to import"
:decode/string tsv->import-data } :decode/string tsv->import-data}
[:vector {:coerce? true} [:vector {:coerce? true}
[:map { :decode/arbitrary (fn [t] [:map { :decode/arbitrary (fn [t]
(if (vector? t) (if (vector? t)
(into {} (map vector [:external-id :client-code :source :vendor-name :date :account-code :location :debit :credit] t)) (into {} (map vector [:external-id :client-code :source :vendor-name :date :account-code :location :debit :credit] t))
t))} t))}
[:external-id [:string {:title "external id" [:external-id [:string {:title "external id"
:min 1 :min 1
:decode/string strip}]] :decode/string strip}]]
[:client-code [:string {:title "client code" [:client-code [:string {:title "client code"
:min 1 :min 1
:decode/string strip}]] :decode/string strip}]]
[:source [:string {:title "source" [:source [:string {:title "source"
:min 1 :min 1
:decode/string strip}]] :decode/string strip}]]
[:vendor-name [:string {:min 1 :decode/string strip}]] [:vendor-name [:string {:min 1 :decode/string strip}]]
[:date [:and clj-date-schema [:date [:and clj-date-schema
[:any {:title "date"}]]] [:any {:title "date"}]]]
[:account-code account-schema] [:account-code account-schema]
[:location [:string { :min 1
:max 2
:decode/string strip}]]
[:debit [:maybe money]]
[:credit [:maybe money]]]]
[:location [:string { :min 1
:max 2
:decode/string strip}]]
[:debit [:maybe money]]
[:credit [:maybe money]]
]]
#_[:string {:decode/string tsv->import-data #_[:string {:decode/string tsv->import-data
:error/message "Clipboard should contain rows to import"}]] ])) :error/message "Clipboard should contain rows to import"}]]]))
@@ -407,19 +407,19 @@
(not (t/equal? (:date entry) (not (t/equal? (:date entry)
(coerce/to-date-time locked-until))))) (coerce/to-date-time locked-until)))))
(all-row-error (str "Client's data is locked until " locked-until)) (all-row-error (str "Client's data is locked until " locked-until))
(not (dollars= (reduce (fnil + 0.0 0.0) 0.0 (map :debit (:line-items entry))) (not (dollars= (reduce (fnil + 0.0 0.0) 0.0 (map :debit (:line-items entry)))
(reduce (fnil + 0.0 0.0) 0.0 (map :credit (:line-items entry))))) (reduce (fnil + 0.0 0.0) 0.0 (map :credit (:line-items entry)))))
(all-row-error (str "Debits '" (all-row-error (str "Debits '"
(reduce (fnil + 0.0 0.0) 0 (map :debit (:line-items entry))) (reduce (fnil + 0.0 0.0) 0 (map :debit (:line-items entry)))
"' and credits '" "' and credits '"
(reduce (fnil + 0.0 0.0) 0 (map :credit (:line-items entry))) (reduce (fnil + 0.0 0.0) 0 (map :credit (:line-items entry)))
"' do not add up.")) "' do not add up."))
(dollars= (reduce (fnil + 0.0 0.0) 0.0 (map :debit (:line-items entry))) (dollars= (reduce (fnil + 0.0 0.0) 0.0 (map :debit (:line-items entry)))
0.0) 0.0)
(all-row-error (str "Cannot have ledger entries that total $0.00") :warn) (all-row-error (str "Cannot have ledger entries that total $0.00") :warn)
:else :else
entry)] entry)]
(update (update
entry entry
:line-items :line-items
@@ -476,7 +476,7 @@
(defn table->entries [table all-vendors all-accounts client-locked-lookup all-client-bank-accounts all-client-locations] (defn table->entries [table all-vendors all-accounts client-locked-lookup all-client-bank-accounts all-client-locations]
(let [lines-with-indexes (for [[i l] (map vector (range) table)] (let [lines-with-indexes (for [[i l] (map vector (range) table)]
(assoc l :index i)) ] (assoc l :index i))]
(into [] (into []
(for [ (for [
[_ lines] (group-by line->id lines-with-indexes) [_ lines] (group-by line->id lines-with-indexes)
@@ -629,9 +629,9 @@
good-entries (filter (fn [e] (and (not (:error (entry-error-types e))) (not (:warn (entry-error-types e))))) entries) good-entries (filter (fn [e] (and (not (:error (entry-error-types e))) (not (:warn (entry-error-types e))))) entries)
bad-entries (filter (fn [e] (:error (entry-error-types e))) entries) bad-entries (filter (fn [e] (:error (entry-error-types e))) entries)
form-errors (reduce (fn [acc [path m status]] form-errors (reduce (fn [acc [path m status]]
(update-in acc path conj [ m status])) (update-in acc path conj [ m status]))
{} {}
errors) errors)
_ (when (seq bad-entries) _ (when (seq bad-entries)
(alog/info ::ledger-import-errors :errors errors) (alog/info ::ledger-import-errors :errors errors)
(throw+ (ex-info "ledger import errors" (throw+ (ex-info "ledger import errors"
@@ -690,13 +690,13 @@
(merge (merge
(apply-middleware-to-all-handlers (apply-middleware-to-all-handlers
(-> (->
{::route/all-page (-> (helper/page-route grid-page :parse-query-params? false) {::route/all-page (-> (helper/page-route grid-page)
(wrap-implied-route-param :external? false)) (wrap-implied-route-param :external? false))
::route/external-page (-> (helper/page-route grid-page :parse-query-params? false) ::route/external-page (-> (helper/page-route grid-page)
(wrap-implied-route-param :external? true)) (wrap-implied-route-param :external? true))
::route/table (helper/table-route grid-page :parse-query-params? false) ::route/table (helper/table-route grid-page)
::route/csv (helper/csv-route grid-page :parse-query-params? false) ::route/csv (helper/csv-route grid-page)
::route/external-import-page external-import-page ::route/external-import-page external-import-page
::route/bank-account-filter bank-account-filter ::route/bank-account-filter bank-account-filter
::route/external-import-parse (-> external-import-parse ::route/external-import-parse (-> external-import-parse
@@ -719,8 +719,8 @@
(wrap-schema-enforce :hx-schema query-schema) (wrap-schema-enforce :hx-schema query-schema)
(wrap-must {:activity :import :subject :ledger}) (wrap-must {:activity :import :subject :ledger})
(wrap-client-redirect-unauthenticated)))) (wrap-client-redirect-unauthenticated))))
balance-sheet/key->handler balance-sheet/key->handler
profit-and-loss/key->handler profit-and-loss/key->handler
cash-flows/key->handler cash-flows/key->handler
investigate/key->handler investigate/key->handler
new/key->handler)) new/key->handler))

View File

@@ -439,8 +439,6 @@ args
[(assoc-in (date-range-field* request) [1 :hx-swap-oob] true) [(assoc-in (date-range-field* request) [1 :hx-swap-oob] true)
(assoc-in (exact-match-id* request) [1 :hx-swap-oob] true)]) (assoc-in (exact-match-id* request) [1 :hx-swap-oob] true)])
:query-schema query-schema :query-schema query-schema
:parse-query-params (fn [p]
(mc/decode query-schema p main-transformer))
:action-buttons (fn [request] :action-buttons (fn [request]
[(when-not (:external? (:route-params request)) (com/button {:color :primary [(when-not (:external? (:route-params request)) (com/button {:color :primary
:hx-get (bidi/path-for ssr-routes/only-routes :hx-get (bidi/path-for ssr-routes/only-routes

View File

@@ -43,8 +43,7 @@
(apply-middleware-to-all-handlers (apply-middleware-to-all-handlers
(-> (->
{::route/investigate investigate {::route/investigate investigate
::route/investigate-results (helper/table-route altered-grid-page :parse-query-params? false ::route/investigate-results (helper/table-route altered-grid-page :push-url? false)}
:push-url? false)}
) )
(fn [h] (fn [h]
(-> h (-> h

View File

@@ -51,7 +51,6 @@
svg/x)]])] svg/x)]])]
[:div {:id "exact-match-id-tag"}])) [:div {:id "exact-match-id-tag"}]))
;; TODO use query-params instead of parsed-query-params
(defn filters [request] (defn filters [request]
[:form#payment-filters {"hx-trigger" "change delay:500ms, keyup changed from:.hot-filter delay:1000ms" [:form#payment-filters {"hx-trigger" "change delay:500ms, keyup changed from:.hot-filter delay:1000ms"
"hx-get" (bidi/path-for ssr-routes/only-routes "hx-get" (bidi/path-for ssr-routes/only-routes
@@ -69,7 +68,7 @@
:value (:vendor (:query-params request)) :value (:vendor (:query-params request))
:value-fn :db/id :value-fn :db/id
:content-fn :vendor/name})) :content-fn :vendor/name}))
(date-range-field* (assoc request :parsed-query-params (:query-params request))) (date-range-field* request)
(com/field {:label "Check #"} (com/field {:label "Check #"}
(com/text-input {:name "check-number" (com/text-input {:name "check-number"
:id "check-number" :id "check-number"
@@ -327,8 +326,6 @@
[(assoc-in (date-range-field* request) [1 :hx-swap-oob] true) [(assoc-in (date-range-field* request) [1 :hx-swap-oob] true)
(assoc-in (exact-match-id* request) [1 :hx-swap-oob] true)]) (assoc-in (exact-match-id* request) [1 :hx-swap-oob] true)])
:query-schema query-schema :query-schema query-schema
:parse-query-params (fn [p]
(mc/decode query-schema p main-transformer))
:action-buttons (fn [request] :action-buttons (fn [request]
(let [[_ _ visible-in-float total-in-float ] (:page-results request)] (let [[_ _ visible-in-float total-in-float ] (:page-results request)]
[(com/pill {:color :primary} " Visible in float " [(com/pill {:color :primary} " Visible in float "
@@ -603,13 +600,13 @@
(def key->handler (def key->handler
(apply-middleware-to-all-handlers (apply-middleware-to-all-handlers
{::route/cleared-page (-> (helper/page-route grid-page :parse-query-params? false) {::route/cleared-page (-> (helper/page-route grid-page)
(wrap-implied-route-param :status :payment-status/cleared)) (wrap-implied-route-param :status :payment-status/cleared))
::route/pending-page (-> (helper/page-route grid-page :parse-query-params? false) ::route/pending-page (-> (helper/page-route grid-page)
(wrap-implied-route-param :status :payment-status/pending)) (wrap-implied-route-param :status :payment-status/pending))
::route/voided-page (-> (helper/page-route grid-page :parse-query-params? false) ::route/voided-page (-> (helper/page-route grid-page)
(wrap-implied-route-param :status :payment-status/voided)) (wrap-implied-route-param :status :payment-status/voided))
::route/all-page (-> (helper/page-route grid-page :parse-query-params? false) ::route/all-page (-> (helper/page-route grid-page)
(wrap-implied-route-param :status nil)) (wrap-implied-route-param :status nil))
::route/delete (-> delete ::route/delete (-> delete
@@ -622,7 +619,7 @@
(wrap-admin)) (wrap-admin))
::route/table (helper/table-route grid-page :parse-query-params? false)} ::route/table (helper/table-route grid-page)}
(fn [h] (fn [h]
(-> h (-> h
(wrap-copy-qp-pqp) (wrap-copy-qp-pqp)

View File

@@ -1,24 +1,32 @@
(ns auto-ap.ssr.pos.cash-drawer-shifts (ns auto-ap.ssr.pos.cash-drawer-shifts
(:require (:require
[auto-ap.datomic [auto-ap.datomic
:refer [add-sorter-fields :refer [add-sorter-fields apply-pagination apply-sort-3 conn merge-query
apply-pagination pull-many query2]]
apply-sort-3 [auto-ap.query-params :refer [wrap-copy-qp-pqp]]
conn
merge-query
pull-many
query2]]
[auto-ap.ssr-routes :as ssr-routes] [auto-ap.ssr-routes :as ssr-routes]
[auto-ap.ssr.components :as com] [auto-ap.ssr.components :as com]
[auto-ap.ssr.grid-page-helper :as helper] [auto-ap.ssr.grid-page-helper :as helper :refer [wrap-apply-sort]]
[auto-ap.ssr.pos.common :refer [date-range-field* total-field*]] [auto-ap.ssr.pos.common :refer [date-range-field* total-field*]]
[auto-ap.ssr.utils :refer [apply-middleware-to-all-handlers clj-date-schema
default-grid-fields-schema wrap-merge-prior-hx
wrap-schema-enforce]]
[auto-ap.time :as atime] [auto-ap.time :as atime]
[bidi.bidi :as bidi] [bidi.bidi :as bidi]
[clj-time.coerce :as c] [clj-time.coerce :as c]
[datomic.api :as dc] [datomic.api :as dc]
[malli.core :as m])) [malli.core :as mc]))
;; always should be fast ;; always should be fast
(def query-schema (mc/schema
[:maybe
(into [:map {:date-range [:date-range :start-date :end-date]}
[:start-date {:optional true}
[:maybe clj-date-schema]]
[:end-date {:optional true}
[:maybe clj-date-schema]]
[:client {:optional true :default nil} [:maybe [:entity-map {:pull [:db/id :client/name]}]]] ]
default-grid-fields-schema)]))
(defn filters [params] (defn filters [params]
[:form {"hx-trigger" "change delay:500ms, keyup changed from:.hot-filter delay:1000ms" [:form {"hx-trigger" "change delay:500ms, keyup changed from:.hot-filter delay:1000ms"
@@ -38,7 +46,7 @@
{:cash-drawer-shift/client [:client/name :db/id :client/code]}]) {:cash-drawer-shift/client [:client/name :db/id :client/code]}])
(defn fetch-ids [db request] (defn fetch-ids [db request]
(let [query-params (:parsed-query-params request) (let [query-params (:query-params request)
query (cond-> {:query {:find [] query (cond-> {:query {:find []
:in ['$ '[?clients ?start-date ?end-date]] :in ['$ '[?clients ?start-date ?end-date]]
:where '[[(iol-ion.query/scan-cash-drawer-shifts $ ?clients ?start-date ?end-date) [[?e _ ?sort-default] ...]]]} :where '[[(iol-ion.query/scan-cash-drawer-shifts $ ?clients ?start-date ?end-date) [[?e _ ?sort-default] ...]]]}
@@ -101,6 +109,7 @@
"Cash Drawer Shifts"]] "Cash Drawer Shifts"]]
:title "Cash drawer shifts" :title "Cash drawer shifts"
:entity-name "Cash drawer shift" :entity-name "Cash drawer shift"
:query-schema query-schema
:route :pos-cash-drawer-shift-table :route :pos-cash-drawer-shift-table
:headers [{:key "client" :headers [{:key "client"
:name "Client" :name "Client"
@@ -134,5 +143,13 @@
(def table* (partial helper/table* grid-page)) (def table* (partial helper/table* grid-page))
(def key->handler (def key->handler
{:pos-cash-drawer-shifts (helper/page-route grid-page) (apply-middleware-to-all-handlers
:pos-cash-drawer-shift-table (helper/table-route grid-page)}) {:pos-cash-drawer-shifts (helper/page-route grid-page)
:pos-cash-drawer-shift-table (helper/table-route grid-page)}
(fn [h]
(-> h
(wrap-copy-qp-pqp)
(wrap-apply-sort grid-page)
(wrap-merge-prior-hx)
(wrap-schema-enforce :query-schema query-schema)
(wrap-schema-enforce :hx-schema query-schema)))))

View File

@@ -4,15 +4,15 @@
[auto-ap.time :as atime] [auto-ap.time :as atime]
[auto-ap.ssr.svg :as svg])) [auto-ap.ssr.svg :as svg]))
(defn date-range-field* [request] (defn date-range-field* [request]
(dr/date-range-field {:value {:start (:start-date (:parsed-query-params request)) (dr/date-range-field {:value {:start (:start-date (:query-params request))
:end (:end-date (:parsed-query-params request))} :end (:end-date (:query-params request))}
:id "date-range"})) :id "date-range"}))
(defn processor-field* [request] (defn processor-field* [request]
(com/field {:label "Processor"} (com/field {:label "Processor"}
(com/radio-card {:size :small (com/radio-card {:size :small
:name "processor" :name "processor"
:value (:processor (:parsed-query-params request)) :value (:processor (:query-params request))
:options [{:value "" :options [{:value ""
:content "All"} :content "All"}
{:value "square" {:value "square"
@@ -37,7 +37,7 @@
:id "total-gte" :id "total-gte"
:hx-preserve "true" :hx-preserve "true"
:class "hot-filter w-20" :class "hot-filter w-20"
:value (:total-gte (:parsed-query-params request)) :value (:total-gte (:query-params request))
:placeholder "0.01" :placeholder "0.01"
:size :small}) :size :small})
[:div.align-baseline [:div.align-baseline
@@ -46,12 +46,12 @@
:hx-preserve "true" :hx-preserve "true"
:id "total-lte" :id "total-lte"
:class "hot-filter w-20" :class "hot-filter w-20"
:value (:total-lte (:parsed-query-params request)) :value (:total-lte (:query-params request))
:placeholder "9999.34" :placeholder "9999.34"
:size :small})])) :size :small})]))
(defn exact-match-id-field* [request] (defn exact-match-id-field* [request]
(when-let [exact-match-id (:exact-match-id (:parsed-query-params request))] (when-let [exact-match-id (:exact-match-id (:query-params request))]
[:div [:div
(com/field {:label "Exact match"} (com/field {:label "Exact match"}
(com/pill {:color :primary} (com/pill {:color :primary}

View File

@@ -1,30 +1,38 @@
(ns auto-ap.ssr.pos.expected-deposits (ns auto-ap.ssr.pos.expected-deposits
(:require (:require
[auto-ap.client-routes :as client-routes]
[auto-ap.datomic [auto-ap.datomic
:refer [add-sorter-fields :refer [add-sorter-fields apply-pagination apply-sort-3 conn merge-query
apply-pagination pull-many query2]]
apply-sort-3
conn
merge-query
pull-many
query2]]
[auto-ap.graphql.utils :refer [extract-client-ids]] [auto-ap.graphql.utils :refer [extract-client-ids]]
[auto-ap.query-params :as query-params] [auto-ap.query-params :as query-params :refer [wrap-copy-qp-pqp]]
[auto-ap.routes.utils
:refer [wrap-client-redirect-unauthenticated wrap-secure]]
[auto-ap.ssr-routes :as ssr-routes] [auto-ap.ssr-routes :as ssr-routes]
[auto-ap.ssr.components :as com] [auto-ap.ssr.components :as com]
[auto-ap.ssr.grid-page-helper :as helper] [auto-ap.ssr.grid-page-helper :as helper :refer [wrap-apply-sort]]
[auto-ap.ssr.pos.common :refer [date-range-field* total-field* exact-match-id-field*]] [auto-ap.ssr.pos.common :refer [date-range-field* exact-match-id-field*]]
[auto-ap.ssr.svg :as svg] [auto-ap.ssr.svg :as svg]
[auto-ap.ssr.utils :refer [apply-middleware-to-all-handlers clj-date-schema
default-grid-fields-schema ref->enum-schema
wrap-merge-prior-hx wrap-schema-enforce]]
[auto-ap.time :as atime] [auto-ap.time :as atime]
[bidi.bidi :as bidi] [bidi.bidi :as bidi]
[clj-time.coerce :as c] [clj-time.coerce :as c]
[datomic.api :as dc] [datomic.api :as dc]
[auto-ap.client-routes :as client-routes] [malli.core :as mc]))
[malli.core :as m]))
(def query-schema (mc/schema
[:maybe
(into [:map {:date-range [:date-range :start-date :end-date]}
[:total-gte {:optional true} [:maybe :double]]
[:total-lte {:optional true} [:maybe :double]]
[:start-date {:optional true}
[:maybe clj-date-schema]]
[:end-date {:optional true}
[:maybe clj-date-schema]]
[:client {:optional true :default nil} [:maybe [:entity-map {:pull [:db/id :client/name]}]]]
[:processor {:optional true} [:maybe (ref->enum-schema "ccp-processor")]]]
default-grid-fields-schema)]))
;; make params parsing composable
(defn filters [request] (defn filters [request]
[:form {"hx-trigger" "change delay:500ms, keyup changed from:.hot-filter delay:1000ms" [:form {"hx-trigger" "change delay:500ms, keyup changed from:.hot-filter delay:1000ms"
@@ -49,7 +57,7 @@
(defn fetch-ids [db request] (defn fetch-ids [db request]
(let [query-params (:parsed-query-params request) (let [query-params (:query-params request)
valid-clients (extract-client-ids (:clients request) valid-clients (extract-client-ids (:clients request)
(:client request) (:client request)
(:client-id query-params) (:client-id query-params)
@@ -139,10 +147,6 @@
:nav com/main-aside-nav :nav com/main-aside-nav
:page-specific-nav filters :page-specific-nav filters
:fetch-page fetch-page :fetch-page fetch-page
:parse-query-params (comp
(query-params/parse-key :total-gte query-params/parse-double)
(query-params/parse-key :total-lte query-params/parse-double)
(helper/default-parse-query-params grid-page))
:oob-render :oob-render
(fn [request] (fn [request]
[(assoc-in (date-range-field* request) [1 :hx-swap-oob] true)]) [(assoc-in (date-range-field* request) [1 :hx-swap-oob] true)])
@@ -155,6 +159,7 @@
"Expected deposits"]] "Expected deposits"]]
:title "Expected deposits" :title "Expected deposits"
:entity-name "Expected deposit" :entity-name "Expected deposit"
:query-schema query-schema
:route :pos-expected-deposit-table :route :pos-expected-deposit-table
:row-buttons (fn [_ e] :row-buttons (fn [_ e]
[ [
@@ -192,6 +197,15 @@
(def row* (partial helper/row* grid-page)) (def row* (partial helper/row* grid-page))
(def table* (partial helper/table* grid-page)) (def table* (partial helper/table* grid-page))
(def key->handler (def key->handler
{:pos-expected-deposits (helper/page-route grid-page) (apply-middleware-to-all-handlers
:pos-expected-deposit-table (helper/table-route grid-page)}) {:pos-expected-deposits (helper/page-route grid-page)
:pos-expected-deposit-table (helper/table-route grid-page)}
(fn [h]
(-> h
(wrap-copy-qp-pqp)
(wrap-apply-sort grid-page)
(wrap-merge-prior-hx)
(wrap-schema-enforce :query-schema query-schema)
(wrap-schema-enforce :hx-schema query-schema)))))

View File

@@ -1,23 +1,33 @@
(ns auto-ap.ssr.pos.refunds (ns auto-ap.ssr.pos.refunds
(:require (:require
[auto-ap.datomic [auto-ap.datomic
:refer [add-sorter-fields :refer [add-sorter-fields apply-pagination apply-sort-3 conn merge-query
apply-pagination pull-many query2]]
apply-sort-3 [auto-ap.query-params :refer [wrap-copy-qp-pqp]]
conn
merge-query
pull-many
query2]]
[auto-ap.query-params :as query-params]
[auto-ap.ssr-routes :as ssr-routes] [auto-ap.ssr-routes :as ssr-routes]
[auto-ap.ssr.components :as com] [auto-ap.ssr.components :as com]
[auto-ap.ssr.grid-page-helper :as helper] [auto-ap.ssr.grid-page-helper :as helper :refer [wrap-apply-sort]]
[auto-ap.ssr.pos.common :refer [date-range-field* total-field*]] [auto-ap.ssr.pos.common :refer [date-range-field* total-field*]]
[auto-ap.ssr.utils :refer [apply-middleware-to-all-handlers clj-date-schema
default-grid-fields-schema wrap-merge-prior-hx
wrap-schema-enforce]]
[auto-ap.time :as atime] [auto-ap.time :as atime]
[bidi.bidi :as bidi] [bidi.bidi :as bidi]
[clj-time.coerce :as c] [clj-time.coerce :as c]
[datomic.api :as dc])) [datomic.api :as dc]
[malli.core :as mc]))
(def query-schema (mc/schema
[:maybe
(into [:map {:date-range [:date-range :start-date :end-date]}
[:total-gte {:optional true} [:maybe :double]]
[:total-lte {:optional true} [:maybe :double]]
[:start-date {:optional true}
[:maybe clj-date-schema]]
[:end-date {:optional true}
[:maybe clj-date-schema]]
[:client {:optional true :default nil} [:maybe [:entity-map {:pull [:db/id :client/name]}]]]]
default-grid-fields-schema)]))
(defn filters [request] (defn filters [request]
[:form {"hx-trigger" "change delay:500ms, keyup changed from:.hot-filter delay:1000ms" [:form {"hx-trigger" "change delay:500ms, keyup changed from:.hot-filter delay:1000ms"
"hx-get" (bidi/path-for ssr-routes/only-routes "hx-get" (bidi/path-for ssr-routes/only-routes
@@ -38,7 +48,7 @@
{:sales-refund/client [:client/name :db/id :client/code]}]) {:sales-refund/client [:client/name :db/id :client/code]}])
(defn fetch-ids [db request] (defn fetch-ids [db request]
(let [query-params (:parsed-query-params request) (let [query-params (:query-params request)
query (cond-> {:query {:find [] query (cond-> {:query {:find []
:in ['$ '[?clients ?start-date ?end-date]] :in ['$ '[?clients ?start-date ?end-date]]
:where '[[(iol-ion.query/scan-sales-refunds $ ?clients ?start-date ?end-date) [[?e _ ?sort-default] ...]]]} :where '[[(iol-ion.query/scan-sales-refunds $ ?clients ?start-date ?end-date) [[?e _ ?sort-default] ...]]]}
@@ -98,10 +108,6 @@
:nav com/main-aside-nav :nav com/main-aside-nav
:page-specific-nav filters :page-specific-nav filters
:fetch-page fetch-page :fetch-page fetch-page
:parse-query-params (comp
(query-params/parse-key :total-gte query-params/parse-double)
(query-params/parse-key :total-lte query-params/parse-double)
(helper/default-parse-query-params grid-page))
:oob-render :oob-render
(fn [request] (fn [request]
[(assoc-in (date-range-field* request) [1 :hx-swap-oob] true)]) [(assoc-in (date-range-field* request) [1 :hx-swap-oob] true)])
@@ -114,6 +120,7 @@
"Refunds"]] "Refunds"]]
:title "Refunds" :title "Refunds"
:entity-name "Refund" :entity-name "Refund"
:query-schema query-schema
:route :pos-refund-table :route :pos-refund-table
:headers [{:key "client" :headers [{:key "client"
:name "Client" :name "Client"
@@ -142,5 +149,13 @@
(def table* (partial helper/table* grid-page)) (def table* (partial helper/table* grid-page))
(def key->handler (def key->handler
{:pos-refunds (helper/page-route grid-page) (apply-middleware-to-all-handlers
:pos-refund-table (helper/table-route grid-page)}) {:pos-refunds (helper/page-route grid-page)
:pos-refund-table (helper/table-route grid-page)}
(fn [h]
(-> h
(wrap-copy-qp-pqp)
(wrap-apply-sort grid-page)
(wrap-merge-prior-hx)
(wrap-schema-enforce :query-schema query-schema)
(wrap-schema-enforce :hx-schema query-schema)))))

View File

@@ -1,25 +1,37 @@
(ns auto-ap.ssr.pos.sales-orders (ns auto-ap.ssr.pos.sales-orders
(:require (:require
[auto-ap.datomic [auto-ap.datomic
:refer [add-sorter-fields :refer [add-sorter-fields apply-pagination apply-sort-3 conn merge-query
apply-pagination pull-many query2]]
apply-sort-3
conn
merge-query
pull-many
query2]]
[auto-ap.datomic.sales-orders :as d-sales] [auto-ap.datomic.sales-orders :as d-sales]
[auto-ap.query-params :as query-params] [auto-ap.query-params :as query-params :refer [wrap-copy-qp-pqp]]
[auto-ap.ssr-routes :as ssr-routes] [auto-ap.ssr-routes :as ssr-routes]
[auto-ap.ssr.components :as com] [auto-ap.ssr.components :as com]
[auto-ap.ssr.grid-page-helper :as helper] [auto-ap.ssr.grid-page-helper :as helper :refer [wrap-apply-sort]]
[auto-ap.ssr.pos.common [auto-ap.ssr.pos.common
:refer [date-range-field* processor-field* total-field*]] :refer [date-range-field* processor-field* total-field*]]
[auto-ap.ssr.svg :as svg] [auto-ap.ssr.svg :as svg]
[auto-ap.ssr.utils :refer [apply-middleware-to-all-handlers clj-date-schema
default-grid-fields-schema ref->enum-schema
wrap-merge-prior-hx wrap-schema-enforce]]
[auto-ap.time :as atime] [auto-ap.time :as atime]
[bidi.bidi :as bidi] [bidi.bidi :as bidi]
[clj-time.coerce :as c] [clj-time.coerce :as c]
[datomic.api :as dc])) [datomic.api :as dc]
[malli.core :as mc]))
(def query-schema (mc/schema
[:maybe
(into [:map {:date-range [:date-range :start-date :end-date]}
[:total-gte {:optional true :default nil} [:maybe :double]]
[:total-lte {:optional true :default nil} [:maybe :double]]
[:start-date {:optional true}
[:maybe clj-date-schema]]
[:end-date {:optional true}
[:maybe clj-date-schema]]
[:client {:optional true :default nil} [:maybe [:entity-map {:pull [:db/id :client/name]}]]]
[:processor {:optional true} [:maybe (ref->enum-schema "ccp-processor")]]]
default-grid-fields-schema)]))
(defn filters [request] (defn filters [request]
[:form {"hx-trigger" "change delay:500ms, keyup changed from:.hot-filter delay:1000ms" [:form {"hx-trigger" "change delay:500ms, keyup changed from:.hot-filter delay:1000ms"
@@ -56,7 +68,7 @@
:class "hot-filter" :class "hot-filter"
:id "category" :id "category"
:hx-preserve "true" :hx-preserve "true"
:value (:category (:parsed-query-params request)) :value (:category (:query-params request))
:placeholder "Fries" :placeholder "Fries"
:size :small}))]]]) :size :small}))]]])
@@ -89,7 +101,7 @@
{:charge/processor [:db/ident]} {:expected-deposit/_charges [:db/id]}]}]) {:charge/processor [:db/ident]} {:expected-deposit/_charges [:db/id]}]}])
(defn fetch-ids [db request] (defn fetch-ids [db request]
(let [query-params (:parsed-query-params request) (let [query-params (:query-params request)
query (cond-> {:query {:find [] query (cond-> {:query {:find []
:in ['$ '[?clients ?start-date ?end-date]] :in ['$ '[?clients ?start-date ?end-date]]
:where '[[(iol-ion.query/scan-sales-orders $ ?clients ?start-date ?end-date) [[?e _ ?sort-default] ...]]]} :where '[[(iol-ion.query/scan-sales-orders $ ?clients ?start-date ?end-date) [[?e _ ?sort-default] ...]]]}
@@ -146,6 +158,7 @@
true true
(merge-query {:query {:find ['?sort-default '?e]}}))] (merge-query {:query {:find ['?sort-default '?e]}}))]
(clojure.pprint/pprint (update-in query [:args] #(drop 1 %)))
(cond->> (query2 query) (cond->> (query2 query)
true (apply-sort-3 query-params) true (apply-sort-3 query-params)
true (apply-pagination query-params)))) true (apply-pagination query-params))))
@@ -167,92 +180,93 @@
(def grid-page (def grid-page
(helper/build (helper/build
{:id "sales-table" {:id "sales-table"
:nav com/main-aside-nav :nav com/main-aside-nav
:page-specific-nav filters :page-specific-nav filters
:fetch-page fetch-page :fetch-page fetch-page
:parse-query-params (comp
(query-params/parse-key :processor #(query-params/parse-keyword "ccp-processor" %))
(query-params/parse-key :total-gte query-params/parse-double)
(query-params/parse-key :total-lte query-params/parse-double)
(helper/default-parse-query-params grid-page))
:oob-render
(fn [request]
[(assoc-in (date-range-field* request) [1 :hx-swap-oob] true)])
:breadcrumbs [[:a {:href (bidi/path-for ssr-routes/only-routes
:company)}
"POS"]
[:a {:href (bidi/path-for ssr-routes/only-routes :query-schema query-schema
:pos-sales)} :oob-render
"Sales"]] (fn [request]
:title "Sales orders" [(assoc-in (date-range-field* request) [1 :hx-swap-oob] true)])
:entity-name "Sales orders" :breadcrumbs [[:a {:href (bidi/path-for ssr-routes/only-routes
:route :pos-sales-table :company)}
:action-buttons (fn [request] "POS"]
(let [{:keys [total tax]} (d-sales/summarize-orders (:ids (fetch-ids (dc/db conn) request)))]
(when (and total tax) [:a {:href (bidi/path-for ssr-routes/only-routes
[ :pos-sales)}
(com/pill {:color :primary} "Sales"]]
(format "Total $%.2f" total) :title "Sales orders"
) :entity-name "Sales orders"
(com/pill {:color :secondary} :route :pos-sales-table
(format "Tax $%.2f" tax ) :action-buttons (fn [request]
)]))) (let [{:keys [total tax]} (d-sales/summarize-orders (:ids (fetch-ids (dc/db conn) request)))]
:row-buttons (fn [_ e] (when (and total tax)
(when (:sales-order/reference-link e) [(com/pill {:color :primary}
[(com/a-icon-button {:href (:sales-order/reference-link e)} (format "Total $%.2f" total))
svg/external-link)])) (com/pill {:color :secondary}
:headers [{:key "client" (format "Tax $%.2f" tax))])))
:name "Client" :row-buttons (fn [_ e]
:sort-key "client" (when (:sales-order/reference-link e)
:hide? (fn [args] [(com/a-icon-button {:href (:sales-order/reference-link e)}
(= (count (:clients args)) 1)) svg/external-link)]))
:render #(-> % :sales-order/client :client/code)} :headers [{:key "client"
{:key "date" :name "Client"
:name "Date" :sort-key "client"
:sort-key "date" :hide? (fn [args]
:render #(atime/unparse-local (:sales-order/date %) atime/standard-time)} (= (count (:clients args)) 1))
{:key "source" :render #(-> % :sales-order/client :client/code)}
:name "Source" {:key "date"
:sort-key "source" :name "Date"
:render (fn [sales-order] :sort-key "date"
(when (:sales-order/source sales-order) :render #(atime/unparse-local (:sales-order/date %) atime/standard-time)}
(com/pill {:color :primary } {:key "source"
(:sales-order/source sales-order))))} :name "Source"
{:key "total" :sort-key "source"
:name "Total" :render (fn [sales-order]
:sort-key "total" (when (:sales-order/source sales-order)
:render #(some->> % :sales-order/total (format "$%.2f"))} (com/pill {:color :primary}
{:key "tax" (:sales-order/source sales-order))))}
:name "Tax" {:key "total"
:sort-key "tax" :name "Total"
:render #(some->> % :sales-order/tax (format "$%.2f"))} :sort-key "total"
{:key "tip" :render #(some->> % :sales-order/total (format "$%.2f"))}
:name "Tip" {:key "tax"
:sort-key "tip" :name "Tax"
:render #(some->> % :sales-order/tip (format "$%.2f"))} :sort-key "tax"
{:key "Payment methods" :render #(some->> % :sales-order/tax (format "$%.2f"))}
:name "Payment Methods" {:key "tip"
:render (fn [sales-order] :name "Tip"
[:div.flex.space-x-2 :sort-key "tip"
(for [payment-method (->> sales-order :sales-order/charges (map :charge/type-name) set)] :render #(some->> % :sales-order/tip (format "$%.2f"))}
(com/pill {:color :primary } {:key "Payment methods"
(condp = payment-method :name "Payment Methods"
"CASH" "cash" :render (fn [sales-order]
"" nil [:div.flex.space-x-2
"ALL" nil (for [payment-method (->> sales-order :sales-order/charges (map :charge/type-name) set)]
"CARD" "card" (com/pill {:color :primary}
"SQUARE_GIFT_CARD" "gift card" (condp = payment-method
"OTHER" "other" "CASH" "cash"
nil)))])}]} "" nil
)) "ALL" nil
"CARD" "card"
"SQUARE_GIFT_CARD" "gift card"
"OTHER" "other"
nil)))])}]}))
(def row* (partial helper/row* grid-page)) (def row* (partial helper/row* grid-page))
(def table* (partial helper/table* grid-page)) (def table* (partial helper/table* grid-page))
(def key->handler (def key->handler
{:pos-sales (helper/page-route grid-page) (apply-middleware-to-all-handlers
:pos-sales-table (helper/table-route grid-page)}) {:pos-sales (helper/page-route grid-page)
:pos-sales-table (helper/table-route grid-page)}
(fn [h]
(-> h
(wrap-copy-qp-pqp)
(wrap-apply-sort grid-page)
(wrap-merge-prior-hx)
(wrap-schema-enforce :query-schema query-schema)
(wrap-schema-enforce :hx-schema query-schema)))))

View File

@@ -1,26 +1,23 @@
(ns auto-ap.ssr.pos.tenders (ns auto-ap.ssr.pos.tenders
(:require (:require
[auto-ap.datomic [auto-ap.datomic
:refer [add-sorter-fields :refer [add-sorter-fields apply-pagination apply-sort-3 conn merge-query
apply-pagination pull-many query2]]
apply-sort-3 [auto-ap.query-params :as query-params :refer [wrap-copy-qp-pqp]]
conn
merge-query
pull-many
query2]]
[auto-ap.query-params :as query-params]
[auto-ap.ssr-routes :as ssr-routes] [auto-ap.ssr-routes :as ssr-routes]
[auto-ap.ssr.components :as com] [auto-ap.ssr.components :as com]
[auto-ap.ssr.grid-page-helper :as helper] [auto-ap.ssr.grid-page-helper :as helper :refer [wrap-apply-sort]]
[auto-ap.ssr.pos.common [auto-ap.ssr.pos.common
:refer [date-range-field* processor-field* total-field*]] :refer [date-range-field* processor-field* total-field*]]
[auto-ap.ssr.svg :as svg] [auto-ap.ssr.svg :as svg]
[auto-ap.ssr.utils :refer [apply-middleware-to-all-handlers clj-date-schema
default-grid-fields-schema ref->enum-schema
wrap-merge-prior-hx wrap-schema-enforce]]
[auto-ap.time :as atime] [auto-ap.time :as atime]
[bidi.bidi :as bidi] [bidi.bidi :as bidi]
[clj-time.coerce :as c] [clj-time.coerce :as c]
[datomic.api :as dc] [datomic.api :as dc]
[malli.core :as m] [malli.core :as mc]))
[malli.transform :as mt2]))
;; always should be fast ;; always should be fast
@@ -37,6 +34,19 @@
(processor-field* request) (processor-field* request)
(total-field* request)]]) (total-field* request)]])
(def query-schema (mc/schema
[:maybe
(into [:map {:date-range [:date-range :start-date :end-date]}
[:total-gte {:optional true} [:maybe :double]]
[:total-lte {:optional true} [:maybe :double]]
[:start-date {:optional true}
[:maybe clj-date-schema]]
[:end-date {:optional true}
[:maybe clj-date-schema]]
[:client {:optional true :default nil} [:maybe [:entity-map {:pull [:db/id :client/name]}]]]
[:processor {:optional true} [:maybe (ref->enum-schema "ccp-processor")]]]
default-grid-fields-schema)]))
(def default-read '[:db/id (def default-read '[:db/id
:charge/reference-link :charge/reference-link
:charge/total :charge/total
@@ -47,7 +57,7 @@
:expected-deposit/_charges [:expected-deposit/date :db/id]}]) :expected-deposit/_charges [:expected-deposit/date :db/id]}])
(defn fetch-ids [db request] (defn fetch-ids [db request]
(let [query-params (:parsed-query-params request) (let [query-params (:query-params request)
query (cond-> {:query {:find [] query (cond-> {:query {:find []
:in ['$ '[?clients ?start-date ?end-date]] :in ['$ '[?clients ?start-date ?end-date]]
:where '[[(iol-ion.query/scan-charges $ ?clients ?start-date ?end-date) [[?e _ ?sort-default] ...]]]} :where '[[(iol-ion.query/scan-charges $ ?clients ?start-date ?end-date) [[?e _ ?sort-default] ...]]]}
@@ -115,11 +125,6 @@
:nav com/main-aside-nav :nav com/main-aside-nav
:page-specific-nav filters :page-specific-nav filters
:fetch-page fetch-page :fetch-page fetch-page
:parse-query-params (comp
(query-params/parse-key :processor #(query-params/parse-keyword "ccp-processor" %))
(query-params/parse-key :total-gte query-params/parse-double)
(query-params/parse-key :total-lte query-params/parse-double)
(helper/default-parse-query-params grid-page))
:oob-render :oob-render
(fn [request] (fn [request]
[(assoc-in (date-range-field* request) [1 :hx-swap-oob] true)]) [(assoc-in (date-range-field* request) [1 :hx-swap-oob] true)])
@@ -132,6 +137,7 @@
"Tenders"]] "Tenders"]]
:title "Tenders" :title "Tenders"
:entity-name "Tender" :entity-name "Tender"
:query-schema query-schema
:route :pos-tender-table :route :pos-tender-table
:row-buttons (fn [request e] :row-buttons (fn [request e]
(when (:charge/reference-link e) (when (:charge/reference-link e)
@@ -177,5 +183,13 @@
(def table* (partial helper/table* grid-page)) (def table* (partial helper/table* grid-page))
(def key->handler (def key->handler
{:pos-tenders (helper/page-route grid-page) (apply-middleware-to-all-handlers
:pos-tender-table (helper/table-route grid-page)}) {:pos-tenders (helper/page-route grid-page)
:pos-tender-table (helper/table-route grid-page)}
(fn [h]
(-> h
(wrap-copy-qp-pqp)
(wrap-apply-sort grid-page)
(wrap-merge-prior-hx)
(wrap-schema-enforce :query-schema query-schema)
(wrap-schema-enforce :hx-schema query-schema)))))

View File

@@ -259,8 +259,6 @@
:page-specific-nav filters :page-specific-nav filters
:fetch-page fetch-page :fetch-page fetch-page
:query-schema query-schema :query-schema query-schema
:parse-query-params (fn [p]
(mc/decode query-schema p main-transformer))
:action-buttons (fn [request] :action-buttons (fn [request]
[(com/button {:color :primary [(com/button {:color :primary
:hx-get (bidi/path-for ssr-routes/only-routes :hx-get (bidi/path-for ssr-routes/only-routes
@@ -364,12 +362,11 @@
;; Handlers ;; Handlers
(def page (helper/page-route grid-page :parse-query-params? false)) (def page (helper/page-route grid-page))
(def table (helper/table-route grid-page :parse-query-params? false)) (def table (helper/table-route grid-page))
(defn csv [request] (def csv (helper/csv-route grid-page))
(helper/csv-route grid-page :parse-query-params? false request))
(def key->handler (def key->handler
(apply-middleware-to-all-handlers (apply-middleware-to-all-handlers

View File

@@ -1,45 +1,31 @@
(ns auto-ap.ssr.users (ns auto-ap.ssr.users
(:require (:require
[auto-ap.datomic [auto-ap.datomic
:refer [add-sorter-fields :refer [add-sorter-fields apply-pagination apply-sort-3 conn merge-query
apply-pagination pull-attr pull-many query2]]
apply-sort-3 [auto-ap.query-params :as query-params :refer [wrap-copy-qp-pqp]]
conn
merge-query
pull-attr
pull-many
query2]]
[auto-ap.query-params :as query-params]
[auto-ap.routes.auth :as auth] [auto-ap.routes.auth :as auth]
[auto-ap.routes.utils [auto-ap.routes.utils
:refer [wrap-admin wrap-client-redirect-unauthenticated]] :refer [wrap-admin wrap-client-redirect-unauthenticated]]
[auto-ap.ssr-routes :as ssr-routes] [auto-ap.ssr-routes :as ssr-routes]
[auto-ap.ssr.components :as com] [auto-ap.ssr.components :as com]
[auto-ap.ssr.form-cursor :as fc] [auto-ap.ssr.form-cursor :as fc]
[auto-ap.ssr.grid-page-helper :as helper] [auto-ap.ssr.grid-page-helper :as helper :refer [wrap-apply-sort]]
[auto-ap.ssr.hx :as hx] [auto-ap.ssr.hx :as hx]
[auto-ap.ssr.nested-form-params :refer [wrap-nested-form-params]] [auto-ap.ssr.nested-form-params :refer [wrap-nested-form-params]]
[auto-ap.ssr.svg :as svg] [auto-ap.ssr.svg :as svg]
[auto-ap.ssr.utils [auto-ap.ssr.utils
:refer [apply-middleware-to-all-handlers :refer [apply-middleware-to-all-handlers default-grid-fields-schema
entity-id entity-id html-response main-transformer many-entity
html-response modal-response ref->enum-schema ref->select-options wrap-entity
main-transformer wrap-form-4xx-2 wrap-merge-prior-hx wrap-schema-enforce]]
many-entity
modal-response
ref->enum-schema
ref->select-options
wrap-entity
wrap-form-4xx-2
wrap-schema-enforce]]
[auto-ap.time :as atime] [auto-ap.time :as atime]
[bidi.bidi :as bidi] [bidi.bidi :as bidi]
[buddy.sign.jwt :as jwt] [buddy.sign.jwt :as jwt]
[clojure.string :as str] [clojure.string :as str]
[config.core :refer [env]] [config.core :refer [env]]
[datomic.api :as dc] [datomic.api :as dc]
[malli.core :as mc] [malli.core :as mc]))
[auto-ap.logging :as alog]))
(defn filters [request] (defn filters [request]
[:form {"hx-trigger" "change delay:500ms, keyup changed from:.hot-filter delay:1000ms" [:form {"hx-trigger" "change delay:500ms, keyup changed from:.hot-filter delay:1000ms"
@@ -53,7 +39,7 @@
(com/text-input {:name "name" (com/text-input {:name "name"
:id "name" :id "name"
:class "hot-filter" :class "hot-filter"
:value (:name (:parsed-query-params request)) :value (:name (:query-params request))
:placeholder "Johnny Testerson" :placeholder "Johnny Testerson"
:size :small})) :size :small}))
@@ -63,7 +49,7 @@
:url (bidi/path-for ssr-routes/only-routes :url (bidi/path-for ssr-routes/only-routes
:company-search) :company-search)
:id (str "client-search") :id (str "client-search")
:value (:client (:parsed-query-params request)) :value (:client (:query-params request))
:value-fn :db/id :value-fn :db/id
:content-fn :client/name})) :content-fn :client/name}))
@@ -71,13 +57,14 @@
(com/text-input {:name "email" (com/text-input {:name "email"
:id "email" :id "email"
:class "hot-filter" :class "hot-filter"
:value (:name (:parsed-query-params request)) :value (:name (:query-params request))
:placeholder "hello@friend.com" :placeholder "hello@friend.com"
:size :small})) :size :small}))
(com/field {:label "Role"} (com/field {:label "Role"}
(com/radio-card {:size :small (com/radio-card {:size :small
:name "role" :name "role"
:value (:role (:query-params request))
:options [{:value "" :options [{:value ""
:content "All"} :content "All"}
{:value "admin" {:value "admin"
@@ -93,6 +80,13 @@
{:value "none" {:value "none"
:content "None"}]}))]]) :content "None"}]}))]])
(def query-schema (mc/schema
[:maybe
(into [:map {}
[:role {:optional true} [:maybe (ref->enum-schema "user-role")]]
[:client {:optional true :default nil} [:maybe [:entity-map {:pull [:db/id :client/name]}]]] ]
default-grid-fields-schema)]))
(def default-read '[:db/id (def default-read '[:db/id
:user/name :user/name
:user/email :user/email
@@ -103,7 +97,7 @@
:user/clients [:client/code :db/id :client/locations :client/name]}]) :user/clients [:client/code :db/id :client/locations :client/name]}])
(defn fetch-ids [db request] (defn fetch-ids [db request]
(let [query-params (:parsed-query-params request) (let [query-params (:query-params request)
query (cond-> {:query {:find [] query (cond-> {:query {:find []
:in '[$ ] :in '[$ ]
:where '[]} :where '[]}
@@ -121,16 +115,16 @@
(merge-query {:query {:find [] (merge-query {:query {:find []
:in ['?ns] :in ['?ns]
:where ['[?e :user/name ?sn] :where ['[?e :user/name ?sn]
'[(clojure.string/upper-case ?sn) ?upper-sn] '[(clojure.string/upper-case ?sn) ?upper-sn]
'[(clojure.string/includes? ?upper-sn ?ns)]]} '[(clojure.string/includes? ?upper-sn ?ns)]]}
:args [(str/upper-case (:name query-params))]}) :args [(str/upper-case (:name query-params))]})
(some->> query-params :email not-empty) (some->> query-params :email not-empty)
(merge-query {:query {:find [] (merge-query {:query {:find []
:in ['?es] :in ['?es]
:where ['[?e :user/email ?se] :where ['[?e :user/email ?se]
'[(clojure.string/upper-case ?se) ?upper-se] '[(clojure.string/upper-case ?se) ?upper-se]
'[(clojure.string/includes? ?upper-se ?es)]]} '[(clojure.string/includes? ?upper-se ?es)]]}
:args [(str/upper-case (:email query-params))]}) :args [(str/upper-case (:email query-params))]})
(some->> query-params :client :db/id) (some->> query-params :client :db/id)
@@ -142,8 +136,7 @@
(some->> query-params :role) (some->> query-params :role)
(merge-query {:query {:find [] (merge-query {:query {:find []
:in ['?r] :in ['?r]
:where ['[?e :user/role ?r] :where ['[?e :user/role ?r] ]}
'[?r :db/ident ?ri]]}
:args [(some->> query-params :role)]}) :args [(some->> query-params :role)]})
@@ -200,19 +193,12 @@
(com/pill {:color :white} (com/pill {:color :white}
(format "%d more" remainder))))]) (format "%d more" remainder))))])
(defn parse-client [client]
(let [client-id (Long/parseLong client)]
(dc/pull (dc/db conn) '[:client/name :db/id] client-id)))
(def grid-page (def grid-page
(helper/build {:id "user-table" (helper/build {:id "user-table"
:nav com/admin-aside-nav :nav com/admin-aside-nav
:page-specific-nav filters :page-specific-nav filters
:fetch-page fetch-page :fetch-page fetch-page
:parse-query-params (comp
(query-params/parse-key :role #(query-params/parse-keyword "user-role" %))
(query-params/parse-key :client parse-client)
(helper/default-parse-query-params grid-page))
:row-buttons (fn [request entity] :row-buttons (fn [request entity]
[(com/button {:hx-post (str (bidi/path-for ssr-routes/only-routes [(com/button {:hx-post (str (bidi/path-for ssr-routes/only-routes
:user-impersonate)) :user-impersonate))
@@ -231,6 +217,7 @@
:title "Users" :title "Users"
:entity-name "User" :entity-name "User"
:route :user-table :route :user-table
:query-schema query-schema
:headers [{:key "name" :headers [{:key "name"
:name "Name" :name "Name"
:sort-key "name" :sort-key "name"
@@ -396,5 +383,10 @@
:params-schema (mc/schema [:map [:db/id entity-id]])))} :params-schema (mc/schema [:map [:db/id entity-id]])))}
(fn [h] (fn [h]
(-> h (-> h
(wrap-copy-qp-pqp)
(wrap-apply-sort grid-page)
(wrap-merge-prior-hx)
(wrap-schema-enforce :query-schema query-schema)
(wrap-schema-enforce :hx-schema query-schema)
(wrap-admin) (wrap-admin)
(wrap-client-redirect-unauthenticated))))) (wrap-client-redirect-unauthenticated)))))

View File

@@ -668,10 +668,7 @@
(with-precision 2 (with-precision 2
(double (.setScale (bigdec d) 2 java.math.RoundingMode/HALF_UP)))) (double (.setScale (bigdec d) 2 java.math.RoundingMode/HALF_UP))))
(defn or-0 [x]
(if (nil? x)
0.0
x))
(defn wrap-implied-route-param [handler & {:as route-params}] (defn wrap-implied-route-param [handler & {:as route-params}]
(fn [request] (fn [request]
@@ -701,4 +698,11 @@
(= "A" location)) (= "A" location))
(throw (ex-info "Exception." {:type "'A' not allowed"}))) (throw (ex-info "Exception." {:type "'A' not allowed"})))
true)) true))
(def default-grid-fields-schema
[
[:sort {:optional true} [:maybe [:any]]]
[:per-page {:optional true :default 25} [:maybe :int]]
[:start {:optional true :default 0} [:maybe :int]]
[:exact-match-id {:optional true} [:maybe entity-id]]])