From fddd3d90078469c806f43a4ae9d37dd06ccb1112 Mon Sep 17 00:00:00 2001 From: Bryce Date: Wed, 27 Sep 2023 23:52:57 -0700 Subject: [PATCH] makes all sales orders use new grid helper --- iol_ion/src/iol_ion/query.clj | 27 +++ resources/public/output.css | 12 ++ resources/schema.edn | 17 ++ scratch-sessions/fix-page-performance.repl | 33 +++ src/clj/auto_ap/ssr/components/aside.clj | 23 +- src/clj/auto_ap/ssr/core.clj | 86 ++++---- src/clj/auto_ap/ssr/grid_page_helper.clj | 1 + .../auto_ap/ssr/pos/cash_drawer_shifts.clj | 177 +++++++++++++++ src/clj/auto_ap/ssr/pos/common.clj | 77 +++++++ src/clj/auto_ap/ssr/pos/expected_deposits.clj | 110 ++++++++++ src/clj/auto_ap/ssr/pos/refunds.clj | 185 ++++++++++++++++ src/clj/auto_ap/ssr/pos/sales_orders.clj | 85 +------- src/clj/auto_ap/ssr/pos/tenders.clj | 204 ++++++++++++++++++ src/cljc/auto_ap/ssr_routes.cljc | 11 +- 14 files changed, 926 insertions(+), 122 deletions(-) create mode 100644 src/clj/auto_ap/ssr/pos/cash_drawer_shifts.clj create mode 100644 src/clj/auto_ap/ssr/pos/common.clj create mode 100644 src/clj/auto_ap/ssr/pos/expected_deposits.clj create mode 100644 src/clj/auto_ap/ssr/pos/refunds.clj create mode 100644 src/clj/auto_ap/ssr/pos/tenders.clj diff --git a/iol_ion/src/iol_ion/query.clj b/iol_ion/src/iol_ion/query.clj index 9449d845..85ad604e 100644 --- a/iol_ion/src/iol_ion/query.clj +++ b/iol_ion/src/iol_ion/query.clj @@ -83,6 +83,33 @@ [c (or (next-day end) #inst "2030-03-05T08:00:00.000-00:00") ]))] [(:e r) (first (:v r)) (second (:v r))])) +(defn scan-charges [db clients start end] + (for [c clients + :let [c (entid db c)] + r (seq (dc/index-range db + :charge/client+date + [c (or start #inst "2001-01-01T08:00:00.000-00:00") ] + [c (or (next-day end) #inst "2030-03-05T08:00:00.000-00:00") ]))] + [(:e r) (first (:v r)) (second (:v r))])) + +(defn scan-sales-refunds [db clients start end] + (for [c clients + :let [c (entid db c)] + r (seq (dc/index-range db + :sales-refund/client+date + [c (or start #inst "2001-01-01T08:00:00.000-00:00") ] + [c (or (next-day end) #inst "2030-03-05T08:00:00.000-00:00") ]))] + [(:e r) (first (:v r)) (second (:v r))])) + +(defn scan-cash-drawer-shifts [db clients start end] + (for [c clients + :let [c (entid db c)] + r (seq (dc/index-range db + :cash-drawer-shift/client+date + [c (or start #inst "2001-01-01T08:00:00.000-00:00") ] + [c (or (next-day end) #inst "2030-03-05T08:00:00.000-00:00") ]))] + [(:e r) (first (:v r)) (second (:v r))])) + (defn scan-invoices [db clients start end] (for [c clients :let [c (entid db c)] diff --git a/resources/public/output.css b/resources/public/output.css index 8242215f..4b5aa9b4 100644 --- a/resources/public/output.css +++ b/resources/public/output.css @@ -1651,6 +1651,18 @@ input:checked + .toggle-bg { margin-bottom: calc(1.5rem * var(--tw-space-y-reverse)); } +.space-y-1 > :not([hidden]) ~ :not([hidden]) { + --tw-space-y-reverse: 0; + margin-top: calc(0.25rem * calc(1 - var(--tw-space-y-reverse))); + margin-bottom: calc(0.25rem * var(--tw-space-y-reverse)); +} + +.space-y-1\.5 > :not([hidden]) ~ :not([hidden]) { + --tw-space-y-reverse: 0; + margin-top: calc(0.375rem * calc(1 - var(--tw-space-y-reverse))); + margin-bottom: calc(0.375rem * var(--tw-space-y-reverse)); +} + .divide-y > :not([hidden]) ~ :not([hidden]) { --tw-divide-y-reverse: 0; border-top-width: calc(1px * calc(1 - var(--tw-divide-y-reverse))); diff --git a/resources/schema.edn b/resources/schema.edn index 287f359d..4d177fba 100644 --- a/resources/schema.edn +++ b/resources/schema.edn @@ -1806,6 +1806,23 @@ :db/valueType :db.type/tuple :db/tupleAttrs [ :payment/client :payment/date] :db/cardinality :db.cardinality/one + :db/index true} + + {:db/ident :charge/client+date + :db/valueType :db.type/tuple + :db/tupleAttrs [ :charge/client :charge/date] + :db/cardinality :db.cardinality/one + :db/index true} + + {:db/ident :sales-refund/client+date + :db/valueType :db.type/tuple + :db/tupleAttrs [ :sales-refund/client :sales-refund/date] + :db/cardinality :db.cardinality/one + :db/index true} + {:db/ident :cash-drawer-shift/client+date + :db/valueType :db.type/tuple + :db/tupleAttrs [ :cash-drawer-shift/client :cash-drawer-shift/date] + :db/cardinality :db.cardinality/one :db/index true}] diff --git a/scratch-sessions/fix-page-performance.repl b/scratch-sessions/fix-page-performance.repl index 4bfe274c..d6f5dc04 100644 --- a/scratch-sessions/fix-page-performance.repl +++ b/scratch-sessions/fix-page-performance.repl @@ -180,4 +180,37 @@ {:user/name "hydrate-tuples"}) +(auto-ap.datomic/audit-transact-batch (->> (dc/q '[:find ?e ?c + :in $ + :where [?e :charge/client ?c]] + (dc/db conn) + ) + (map (fn [[i c]] + {:db/id i + :charge/client c}))) + + {:user/name "hydrate-tuples"}) + +(auto-ap.datomic/audit-transact-batch (->> (dc/q '[:find ?e ?c + :in $ + :where [?e :cash-drawer-shift/client ?c]] + (dc/db conn) + ) + (map (fn [[i c]] + {:db/id i + :cash-drawer-shift/client c}))) + + {:user/name "hydrate-tuples"}) + +(auto-ap.datomic/audit-transact-batch (->> (dc/q '[:find ?e ?c + :in $ + :where [?e :sales-refund/client ?c]] + (dc/db conn) + ) + (map (fn [[i c]] + {:db/id i + :sales-refund/client c}))) + + {:user/name "hydrate-tuples"}) + ) diff --git a/src/clj/auto_ap/ssr/components/aside.clj b/src/clj/auto_ap/ssr/components/aside.clj index 1d843d2c..bbbbc761 100644 --- a/src/clj/auto_ap/ssr/components/aside.clj +++ b/src/clj/auto_ap/ssr/components/aside.clj @@ -10,7 +10,7 @@ [:a (-> params (dissoc :icon) (assoc :type "button") - (update :class str " cursor-pointer flex items-center p-2 w-full text-sm text-gray-600 rounded-lg transition duration-75 group hover:bg-gray-100 dark:text-white dark:hover:bg-gray-700") + (update :class str " cursor-pointer flex items-center p-2 w-full text-xs text-gray-600 rounded-lg transition duration-75 group hover:bg-gray-100 dark:text-white dark:hover:bg-gray-700") (assoc :hx-indicator "find .htmx-indicator") (assoc :hx-select "#app-contents") (assoc :hx-target "#app-contents") @@ -28,7 +28,7 @@ (svg/spinner-primary {:class "inline w-4 h-4 text-white"})]]]) (defn sub-menu- [params & children] - [:ul {:id (:id params) :class "hidden py-2 space-y-2"} + [:ul {:id (:id params) :class "hidden py-2 space-y-1.5"} (for [c children] [:li (update-in c [1 1 :class ] str " flex items-center p-2 pl-11 w-full text-base font-normal text-gray-900 rounded-lg transition duration-75 group hover:bg-gray-100 dark:text-white dark:hover:bg-gray-700")])]) @@ -148,7 +148,7 @@ ")]]) (defn main-aside-nav- [] - [:ul {:class "space-y-2"} + [:ul {:class "space-y-1"} [:li (menu-button- {:icon svg/pie @@ -178,11 +178,22 @@ :icon svg/receipt-register-1} "Sales") (sub-menu- {:id "dropdown-sales"} - (menu-button- {:href (str (bidi/path-for client-routes/routes + (menu-button- {:href (str (bidi/path-for ssr-routes/only-routes :pos-sales) "?date-range=week")} "Sales") - (menu-button- {:href (bidi/path-for client-routes/routes - :expected-deposits)} "Expected Deposits") + (menu-button- {:href (str (bidi/path-for ssr-routes/only-routes + :pos-expected-deposits) + "?date-range=week")} "Expected Deposits") + (menu-button- {:href (str (bidi/path-for ssr-routes/only-routes + :pos-tenders) + "?date-range=week")} "Tenders") + + (menu-button- {:href (str (bidi/path-for ssr-routes/only-routes + :pos-refunds) + "?date-range=week")} "Refunds") + (menu-button- {:href (str (bidi/path-for ssr-routes/only-routes + :pos-cash-drawer-shifts) + "?date-range=week")} "Cash drawer shifts") #_(menu-button- {:href "Sales"} "Cash Shifts") #_(menu-button- {:href "Sales"} "Tenders"))] [:li diff --git a/src/clj/auto_ap/ssr/core.clj b/src/clj/auto_ap/ssr/core.clj index a32a3bf2..e0c4f160 100644 --- a/src/clj/auto_ap/ssr/core.clj +++ b/src/clj/auto_ap/ssr/core.clj @@ -13,49 +13,57 @@ [auto-ap.ssr.company.reports :as company-reports] [auto-ap.ssr.invoice.glimpse :as invoice-glimpse] [auto-ap.ssr.pos.sales-orders :as pos-sales] + [auto-ap.ssr.pos.refunds :as pos-refunds] + [auto-ap.ssr.pos.expected-deposits :as pos-expected-deposits] + [auto-ap.ssr.pos.cash-drawer-shifts :as pos-cash-drawer-shifts] + [auto-ap.ssr.pos.tenders :as pos-tenders] [auto-ap.routes.ezcater-xls :as ezcater-xls] [auto-ap.ssr.company :as company])) ;; from auto-ap.ssr-routes, because they're shared -(def key->handler (into {:logout auth/logout - :admin-history (wrap-client-redirect-unauthenticated (wrap-secure (wrap-admin history/page))) - :admin-history-search (wrap-client-redirect-unauthenticated (wrap-secure (wrap-admin history/page))) - :admin-history-inspect (wrap-client-redirect-unauthenticated (wrap-secure (wrap-admin history/inspect))) - :active-client (wrap-client-redirect-unauthenticated (wrap-secure (wrap-secure company-dropdown/active-client))) - :company-dropdown-search-results - (wrap-client-redirect-unauthenticated (wrap-secure company-dropdown/dropdown-search-results)) - :company (wrap-client-redirect-unauthenticated (wrap-secure company/page)) - :company-1099 (wrap-client-redirect-unauthenticated (wrap-secure company-1099/page)) - :company-1099-vendor-table (wrap-client-redirect-unauthenticated (wrap-secure company-1099/vendor-table)) - :company-1099-vendor-dialog (wrap-client-redirect-unauthenticated (wrap-secure company-1099/vendor-dialog)) - :company-1099-vendor-save (wrap-client-redirect-unauthenticated (wrap-secure company-1099/vendor-save)) - :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-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-reauthenticate (wrap-client-redirect-unauthenticated (wrap-admin company-yodlee/reauthenticate)) - :company-reports (wrap-client-redirect-unauthenticated (wrap-secure company-reports/page)) - :company-reports-table (wrap-client-redirect-unauthenticated (wrap-secure company-reports/table)) - :company-reports-delete (wrap-client-redirect-unauthenticated (wrap-admin company-reports/delete-report)) - :invoice-glimpse (wrap-client-redirect-unauthenticated (wrap-admin invoice-glimpse/page)) - :invoice-glimpse-upload (wrap-client-redirect-unauthenticated (wrap-admin invoice-glimpse/upload)) - :invoice-glimpse-textract-invoice (wrap-client-redirect-unauthenticated (wrap-admin invoice-glimpse/textract-invoice)) - :invoice-glimpse-create-invoice (wrap-client-redirect-unauthenticated (wrap-admin invoice-glimpse/create-invoice)) - :invoice-glimpse-update-textract-invoice (wrap-client-redirect-unauthenticated (wrap-admin invoice-glimpse/update-textract-invoice)) - :transaction-insights (wrap-client-redirect-unauthenticated (wrap-admin insights/page)) - :transaction-insight-table (wrap-client-redirect-unauthenticated (wrap-admin insights/insight-table)) - :transaction-insight-rows (wrap-client-redirect-unauthenticated (wrap-admin insights/transaction-rows)) - :transaction-insight-code (wrap-client-redirect-unauthenticated (wrap-admin insights/code)) - :transaction-insight-disapprove (wrap-client-redirect-unauthenticated (wrap-admin insights/disapprove)) - :transaction-insight-explain (wrap-client-redirect-unauthenticated (wrap-admin insights/explain)) - :admin-ezcater-xls (wrap-client-redirect-unauthenticated (wrap-admin ezcater-xls/page)) - :search (wrap-client-redirect-unauthenticated (wrap-secure search/dialog-contents))} - - pos-sales/key->handler)) +(def key->handler + (-> {:logout auth/logout + :admin-history (wrap-client-redirect-unauthenticated (wrap-secure (wrap-admin history/page))) + :admin-history-search (wrap-client-redirect-unauthenticated (wrap-secure (wrap-admin history/page))) + :admin-history-inspect (wrap-client-redirect-unauthenticated (wrap-secure (wrap-admin history/inspect))) + :active-client (wrap-client-redirect-unauthenticated (wrap-secure (wrap-secure company-dropdown/active-client))) + :company-dropdown-search-results + (wrap-client-redirect-unauthenticated (wrap-secure company-dropdown/dropdown-search-results)) + :company (wrap-client-redirect-unauthenticated (wrap-secure company/page)) + :company-1099 (wrap-client-redirect-unauthenticated (wrap-secure company-1099/page)) + :company-1099-vendor-table (wrap-client-redirect-unauthenticated (wrap-secure company-1099/vendor-table)) + :company-1099-vendor-dialog (wrap-client-redirect-unauthenticated (wrap-secure company-1099/vendor-dialog)) + :company-1099-vendor-save (wrap-client-redirect-unauthenticated (wrap-secure company-1099/vendor-save)) + :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-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-reauthenticate (wrap-client-redirect-unauthenticated (wrap-admin company-yodlee/reauthenticate)) + :company-reports (wrap-client-redirect-unauthenticated (wrap-secure company-reports/page)) + :company-reports-table (wrap-client-redirect-unauthenticated (wrap-secure company-reports/table)) + :company-reports-delete (wrap-client-redirect-unauthenticated (wrap-admin company-reports/delete-report)) + :invoice-glimpse (wrap-client-redirect-unauthenticated (wrap-admin invoice-glimpse/page)) + :invoice-glimpse-upload (wrap-client-redirect-unauthenticated (wrap-admin invoice-glimpse/upload)) + :invoice-glimpse-textract-invoice (wrap-client-redirect-unauthenticated (wrap-admin invoice-glimpse/textract-invoice)) + :invoice-glimpse-create-invoice (wrap-client-redirect-unauthenticated (wrap-admin invoice-glimpse/create-invoice)) + :invoice-glimpse-update-textract-invoice (wrap-client-redirect-unauthenticated (wrap-admin invoice-glimpse/update-textract-invoice)) + :transaction-insights (wrap-client-redirect-unauthenticated (wrap-admin insights/page)) + :transaction-insight-table (wrap-client-redirect-unauthenticated (wrap-admin insights/insight-table)) + :transaction-insight-rows (wrap-client-redirect-unauthenticated (wrap-admin insights/transaction-rows)) + :transaction-insight-code (wrap-client-redirect-unauthenticated (wrap-admin insights/code)) + :transaction-insight-disapprove (wrap-client-redirect-unauthenticated (wrap-admin insights/disapprove)) + :transaction-insight-explain (wrap-client-redirect-unauthenticated (wrap-admin insights/explain)) + :admin-ezcater-xls (wrap-client-redirect-unauthenticated (wrap-admin ezcater-xls/page)) + :search (wrap-client-redirect-unauthenticated (wrap-secure search/dialog-contents))} + (into pos-sales/key->handler) + (into pos-expected-deposits/key->handler) + (into pos-tenders/key->handler) + (into pos-cash-drawer-shifts/key->handler) + (into pos-refunds/key->handler))) diff --git a/src/clj/auto_ap/ssr/grid_page_helper.clj b/src/clj/auto_ap/ssr/grid_page_helper.clj index 480dbc46..fbd1fb7f 100644 --- a/src/clj/auto_ap/ssr/grid_page_helper.clj +++ b/src/clj/auto_ap/ssr/grid_page_helper.clj @@ -88,6 +88,7 @@ :thead-params {:hx-get (bidi/path-for ssr-routes/only-routes (:route grid-spec)) :hx-target (str "#" (:id grid-spec)) + :hx-indicator (str "#" (:id grid-spec)) :hx-trigger "sorted once" :hx-vals "js:{\"toggle-sort\": event.detail.key || \"\"}"} :headers diff --git a/src/clj/auto_ap/ssr/pos/cash_drawer_shifts.clj b/src/clj/auto_ap/ssr/pos/cash_drawer_shifts.clj new file mode 100644 index 00000000..13e56c06 --- /dev/null +++ b/src/clj/auto_ap/ssr/pos/cash_drawer_shifts.clj @@ -0,0 +1,177 @@ +(ns auto-ap.ssr.pos.cash-drawer-shifts + (:require + [auto-ap.datomic + :refer [add-sorter-fields + apply-pagination + apply-sort-3 + conn + merge-query + pull-many + query2]] + [auto-ap.graphql.utils :refer [extract-client-ids]] + [auto-ap.routes.utils + :refer [wrap-client-redirect-unauthenticated wrap-secure]] + [auto-ap.ssr.pos.common :refer [date-range-field* processor-field* total-field*]] + [auto-ap.ssr-routes :as ssr-routes] + [auto-ap.ssr.components :as com] + [auto-ap.ssr.grid-page-helper :as helper] + [auto-ap.ssr.svg :as svg] + [auto-ap.time :as atime] + [bidi.bidi :as bidi] + [clj-time.coerce :as c] + [datomic.api :as dc] + [clojure.set :as set])) + +;; always should be fast +;; make params parsing composable + +(defn filters [params] + [:form {"hx-trigger" "change delay:500ms, keyup changed from:.hot-filter delay:1000ms" + "hx-get" (bidi/path-for ssr-routes/only-routes + :pos-cash-drawer-shift-table) + "hx-target" "#cash-drawer-shift-table" + "hx-indicator" "#cash-drawer-shift-table" + #_#_:hx-disabled-elt "find fieldset"} + + [:fieldset.space-y-6 + (date-range-field* params) + (total-field* params)]]) + +(defn <-datomic [result] + (cond-> result + true (update :cash-drawer-shift/date c/from-date))) + +(def default-read '[* + {:cash-drawer-shift/client [:client/name :db/id :client/code]}]) + +(defn fetch-ids [db args] + (let [query-params (:parsed-query-params args) + valid-clients (extract-client-ids (:clients args) + (:client-id query-params) + (when (:client-code query-params) + [:client/code (:client-code query-params)])) + valid-clients (->> valid-clients + (take 10) + set) + start-date (some-> args + :parsed-query-params + :start-date + (atime/parse atime/normal-date)) + end-date (some-> args + :parsed-query-params + :end-date + (atime/parse atime/normal-date)) + query (cond-> {:query {:find [] + :in ['$ '[?clients ?start-date ?end-date]] + :where '[[(iol-ion.query/scan-cash-drawer-shifts $ ?clients ?start-date ?end-date) [[?e _ ?sort-default] ...]]]} + :args [db [valid-clients + (some-> start-date c/to-date) + (some-> end-date c/to-date )]]} + (:sort query-params) (add-sorter-fields {"client" ['[?e :cash-drawer-shift/client ?c] + '[?c :client/name ?sort-client]] + "date" ['[?e :cash-drawer-shift/date ?sort-date]] + "paid-in" ['[?e :cash-drawer-shift/paid-in ?sort-paid-in]] + "paid-out" ['[?e :cash-drawer-shift/paid-out ?sort-paid-out]] + "expected-cash" ['[?e :cash-drawer-shift/expected-cash ?sort-expected-cash]] + "opened-cash" ['[?e :cash-drawer-shift/opened-cash ?sort-opened-cash]] + } + query-params) + + (:exact-match-id query-params) + (merge-query {:query {:in ['?e] + :where []} + :args [(:exact-match-id query-params)]}) + + start-date + (merge-query {:query {:in '[?start-date] + :where ['[?e :cash-drawer-shift/date ?date] + '[(>= ?date ?start-date)]]} + :args [(c/to-date start-date)]}) + + end-date + (merge-query {:query {:in '[?end-date] + :where ['[?e :cash-drawer-shift/date ?date] + '[(<= ?date ?end-date)]]} + :args [(c/to-date end-date)]}) + + true + (merge-query {:query {:find ['?sort-default '?e] + :where ['[?e :cash-drawer-shift/date ?sort-default]]}}))] + + (cond->> (query2 query) + true (apply-sort-3 query-params) + true (apply-pagination query-params)))) + +(defn hydrate-results [ids db _] + (let [results (->> (pull-many db default-read ids) + (group-by :db/id)) + cash-drawer-shifts (->> ids + (map results) + (map first) + (mapv <-datomic) + )] + cash-drawer-shifts)) + +(defn fetch-page [_ args] + (let [db (dc/db conn) + {ids-to-retrieve :ids matching-count :count} (fetch-ids db args)] + + [(->> (hydrate-results ids-to-retrieve db args)) + matching-count])) + +(def grid-page {:id "cash-drawer-shift-table" + :nav (com/main-aside-nav) + :page-specific-nav filters + :id-fn :db/id + :fetch-page fetch-page + :oob-render + (fn [_ params] + [(assoc-in (date-range-field* params) [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 + :pos-cash-drawer-shifts)} + "Cash Drawer Shifts"]] + :title "Cash drawer shifts" + :entity-name "Cash drawer shift" + :route :pos-cash-drawer-shift-table + :action-buttons (fn [_ args]) + :row-buttons (fn [_ e]) + :headers [{:key "client" + :name "Client" + :sort-key "client" + :hide? (fn [args] + (= (count (:clients args)) 1)) + :render #(-> % :cash-drawer-shift/client :client/code)} + {:key "date" + :name "Date" + :sort-key "date" + :render #(atime/unparse-local (:cash-drawer-shift/date %) atime/standard-time)} + {:key "paid-in" + :name "Paid in" + :sort-key "paid-in" + :render #(some->> % :cash-drawer-shift/paid-in (format "$%.2f"))} + {:key "paid-out" + :name "Paid out" + :sort-key "paid-out" + :render #(some->> % :cash-drawer-shift/paid-out (format "$%.2f"))} + {:key "expected-cash" + :name "Expected cash" + :sort-key "expected-cash" + :render #(some->> % :cash-drawer-shift/expected-cash (format "$%.2f"))} + {:key "opened-cash" + :name "Opened cash" + :sort-key "opened-cash" + :render #(some->> % :cash-drawer-shift/opened-cash (format "$%.2f"))} + ]}) + +(def row* (partial helper/row* grid-page)) +(def table* (partial helper/table* grid-page)) +(def table (partial helper/table grid-page)) +(def page (partial helper/page grid-page)) + +(def key->handler + {:pos-cash-drawer-shifts (wrap-client-redirect-unauthenticated (wrap-secure page)) + :pos-cash-drawer-shift-table (wrap-client-redirect-unauthenticated (wrap-secure table))}) diff --git a/src/clj/auto_ap/ssr/pos/common.clj b/src/clj/auto_ap/ssr/pos/common.clj new file mode 100644 index 00000000..b87b78c7 --- /dev/null +++ b/src/clj/auto_ap/ssr/pos/common.clj @@ -0,0 +1,77 @@ +(ns auto-ap.ssr.pos.common + (:require [auto-ap.ssr.components :as com] + [auto-ap.time :as atime])) + + +(defn date-range-field* [params] + [:div#date-range {} + (com/field {:label "Date Range"} + [:div.space-y-4 + [:div + (com/button-group {:name "date-range"} + (com/button-group-button {:size :small :value "all" :hx-trigger "click"} "All") + (com/button-group-button {:size :small :value "week" :hx-trigger "click"} "Week") + (com/button-group-button {:size :small :value "month" :hx-trigger "click"} "Month") + (com/button-group-button {:size :small :value "year" :hx-trigger "click"} "Year")) + ] + [:div.flex.space-x-1.items-baseline + (com/date-input {:name "start-date" + :value (some-> params + :parsed-query-params + :start-date + (atime/parse atime/normal-date) + (atime/unparse-local + atime/normal-date)) + :placeholder "Date" + :size :small}) + + (com/date-input {:name "end-date" + :value (some-> params + :parsed-query-params + :end-date + (atime/parse atime/normal-date) + (atime/unparse-local + atime/normal-date)) + :placeholder "Date" + :size :small})]] + )]) +(defn processor-field* [params] + (com/field {:label "Processor"} + (com/radio {:size :small + :name "processor" + :options [{:value "" + :content "All"} + {:value "square" + :content [:div.flex.space-x-2 [:img.align-center {:src "/img/square.png" :style {:width "16px" :height "16px"}}] [:div "Square"]]} + {:value "doordash" + :content [:div.flex.space-x-2 [:img.align-center {:src "/img/doordash.png" :style {:width "16px" :height "16px"}}] [:div "Doordash"]]} + {:value "uber-eats" + :content [:div.flex.space-x-2 [:img.align-center {:src "/img/ubereats.png" :style {:width "16px" :height "16px"}}] [:div "Uber eats"]]} + {:value "grubhub" + :content [:div.flex.space-x-2 [:img.align-center {:src "/img/grubhub.png" :style {:width "16px" :height "16px"}}] [:div "Grubhub"]]} + {:value "koala" + :content [:div.flex.space-x-2 [:img.align-center {:src "/img/koala.png" :style {:width "16px" :height "16px"}}] [:div "Koala"]]} + {:value "ezcater" + :content [:div.flex.space-x-2 [:img.align-center {:src "/img/ezcater.png" :style {:width "16px" :height "16px"}}] [:div "EZCater"]]} + {:value "na" + :content "No Processor"}]}))) + +(defn total-field* [params] + (com/field {:label "Total"} + [:div.flex.space-x-4.items-baseline + (com/money-input {:name "total-gte" + :id "total-gte" + :hx-preserve "true" + :class "hot-filter" + :value (:total-gte (:parsed-query-params params)) + :placeholder "0.01" + :size :small}) + [:div.align-baseline + "to"] + (com/money-input {:name "total-lte" + :hx-preserve "true" + :id "total-lte" + :class "hot-filter" + :value (:total-lte (:parsed-query-params params)) + :placeholder "9999.34" + :size :small})])) diff --git a/src/clj/auto_ap/ssr/pos/expected_deposits.clj b/src/clj/auto_ap/ssr/pos/expected_deposits.clj new file mode 100644 index 00000000..142c0b3d --- /dev/null +++ b/src/clj/auto_ap/ssr/pos/expected_deposits.clj @@ -0,0 +1,110 @@ +(ns auto-ap.ssr.pos.expected-deposits + (:require + [auto-ap.datomic.expected-deposit :as d-expected-deposit] + [auto-ap.routes.utils + :refer [wrap-client-redirect-unauthenticated wrap-secure]] + [auto-ap.ssr-routes :as ssr-routes] + [auto-ap.ssr.components :as com] + [auto-ap.ssr.grid-page-helper :as helper] + [auto-ap.ssr.pos.common :refer [date-range-field* total-field*]] + [auto-ap.ssr.svg :as svg] + [auto-ap.time :as atime] + [bidi.bidi :as bidi])) + +;; TODO refunds +;; always should be fast +;; make params parsing composable + +(defn filters [params] + [:form {"hx-trigger" "change delay:500ms, keyup changed from:.hot-filter delay:1000ms" + "hx-get" (bidi/path-for ssr-routes/only-routes + :pos-expected-deposit-table) + "hx-target" "#expected-deposit-table" + "hx-indicator" "#expected-deposit-table" + #_#_:hx-disabled-elt "find fieldset"} + + [:fieldset.space-y-6 + (date-range-field* params) + (total-field* params)]]) + +(defn args->graphql-params [args] + {:clients (:clients args) + :start (:start (:parsed-query-params args)) + :sort (:sort (:parsed-query-params args)) + :per-page (:per-page (:parsed-query-params args)) + :exact-match-id (some-> (:parsed-query-params args) :exact-match-id Long/parseLong) + :date-range {:start (some-> args + :parsed-query-params + :start-date + (atime/parse atime/normal-date)) + :end (some-> args + :parsed-query-params + :end-date + (atime/parse atime/normal-date))} + :total-gte (some-> args :raw-query-params (get "total-gte") not-empty (#(if (string? %) (Double/parseDouble %) (double %)))) + :total-lte (some-> args :raw-query-params (get "total-lte") not-empty (#(if (string? %) (Double/parseDouble %) (double %))))}) + +(def grid-page {:id "expected-deposit-table" + :nav (com/main-aside-nav) + :page-specific-nav filters + :id-fn :db/id + :fetch-page (fn [_ args] + (d-expected-deposit/get-graphql + (args->graphql-params args))) + :oob-render + (fn [_ params] + [(assoc-in (date-range-field* params) [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 + :pos-expected-deposits)} + "Expected deposits"]] + :title "Expected deposits" + :entity-name "Expected deposit" + :route :pos-expected-deposit-table + :action-buttons (fn [_ args] + #_(let [{:keys [total tax]} (d-sales/summarize-graphql (args->graphql-params args))] + [ + (com/pill {:color :primary} + (format "Total $%.2f" total) + ) + (com/pill {:color :secondary} + (format "Tax $%.2f" tax ) + )])) + :row-buttons (fn [_ e] + (when (:expected-deposit/reference-link e) + [(com/a-icon-button {:href (:expected-deposit/reference-link e)} + svg/external-link)])) + :headers [{:key "client" + :name "Client" + :sort-key "client" + :hide? (fn [args] + (= (count (:clients args)) 1)) + :render #(-> % :expected-deposit/client :client/code)} + {:key "date" + :name "Date" + :sort-key "date" + :render #(atime/unparse-local (:expected-deposit/date %) atime/standard-time)} + {:key "sales-date" + :name "Sales Date" + :sort-key "sales-date" + :render #(atime/unparse-local (:expected-deposit/sales-date %) atime/standard-time)} + {:key "total" + :name "Total" + :sort-key "total" + :render #(some->> % :expected-deposit/total (format "$%.2f"))} + {:key "fee" + :name "Fee" + :sort-key "fee" + :render #(some->> % :expected-deposit/fee (format "$%.2f"))}]}) + +(def row* (partial helper/row* grid-page)) +(def table* (partial helper/table* grid-page)) +(def table (partial helper/table grid-page)) +(def page (partial helper/page grid-page)) + +(def key->handler + {:pos-expected-deposits (wrap-client-redirect-unauthenticated (wrap-secure page)) + :pos-expected-deposit-table (wrap-client-redirect-unauthenticated (wrap-secure table))}) diff --git a/src/clj/auto_ap/ssr/pos/refunds.clj b/src/clj/auto_ap/ssr/pos/refunds.clj new file mode 100644 index 00000000..e767901b --- /dev/null +++ b/src/clj/auto_ap/ssr/pos/refunds.clj @@ -0,0 +1,185 @@ +(ns auto-ap.ssr.pos.refunds + (:require + [auto-ap.datomic + :refer [add-sorter-fields + apply-pagination + apply-sort-3 + conn + merge-query + pull-many + query2]] + [auto-ap.graphql.utils :refer [extract-client-ids]] + [auto-ap.routes.utils + :refer [wrap-client-redirect-unauthenticated wrap-secure]] + [auto-ap.ssr.pos.common :refer [date-range-field* processor-field* total-field*]] + [auto-ap.ssr-routes :as ssr-routes] + [auto-ap.ssr.components :as com] + [auto-ap.ssr.grid-page-helper :as helper] + [auto-ap.ssr.svg :as svg] + [auto-ap.time :as atime] + [bidi.bidi :as bidi] + [clj-time.coerce :as c] + [datomic.api :as dc] + [clojure.set :as set])) + +;; TODO refunds +;; always should be fast +;; make params parsing composable + +(defn filters [params] + [:form {"hx-trigger" "change delay:500ms, keyup changed from:.hot-filter delay:1000ms" + "hx-get" (bidi/path-for ssr-routes/only-routes + :pos-refund-table) + "hx-target" "#refund-table" + "hx-indicator" "#refund-table" + #_#_:hx-disabled-elt "find fieldset"} + + [:fieldset.space-y-6 + (date-range-field* params) + (total-field* params)]]) + +(defn <-datomic [result] + (cond-> result + true (update :sales-refund/date c/from-date))) + +(def default-read '[* + {:sales-refund/client [:client/name :db/id :client/code]}]) + +(defn fetch-ids [db args] + (let [query-params (:parsed-query-params args) + valid-clients (extract-client-ids (:clients args) + (:client-id query-params) + (when (:client-code query-params) + [:client/code (:client-code query-params)])) + valid-clients (->> valid-clients + (take 10) + set) + start-date (some-> args + :parsed-query-params + :start-date + (atime/parse atime/normal-date)) + end-date (some-> args + :parsed-query-params + :end-date + (atime/parse atime/normal-date)) + total-gte (some-> args :parsed-query-params :total-gte not-empty (#(if (string? %) (Double/parseDouble %) (double %)))) + total-lte (some-> args :parsed-query-params :total-lte not-empty (#(if (string? %) (Double/parseDouble %) (double %)))) + query (cond-> {:query {:find [] + :in ['$ '[?clients ?start-date ?end-date]] + :where '[[(iol-ion.query/scan-sales-refunds $ ?clients ?start-date ?end-date) [[?e _ ?sort-default] ...]]]} + :args [db [valid-clients + (some-> start-date c/to-date) + (some-> end-date c/to-date )]]} + (:sort query-params) (add-sorter-fields {"client" ['[?e :sales-refund/client ?c] + '[?c :client/name ?sort-client]] + "date" ['[?e :sales-refund/date ?sort-date]] + "total" ['[?e :sales-refund/total ?sort-total]] + "fee" ['[?e :sales-refund/fee ?sort-tip]] + "type" ['[?e :sales-refund/type ?type]]} + query-params) + + (:exact-match-id query-params) + (merge-query {:query {:in ['?e] + :where []} + :args [(:exact-match-id query-params)]}) + + total-gte + (merge-query {:query {:in ['?total-gte] + :where ['[?e :sales-refund/total ?a] + '[(>= ?a ?total-gte)]]} + :args [total-gte]}) + + total-lte + (merge-query {:query {:in ['?total-lte] + :where ['[?e :sales-refund/total ?a] + '[(<= ?a ?total-lte)]]} + :args [total-lte]}) + + start-date + (merge-query {:query {:in '[?start-date] + :where ['[?e :sales-refund/date ?date] + '[(>= ?date ?start-date)]]} + :args [(c/to-date start-date)]}) + + end-date + (merge-query {:query {:in '[?end-date] + :where ['[?e :sales-refund/date ?date] + '[(<= ?date ?end-date)]]} + :args [(c/to-date end-date)]}) + + true + (merge-query {:query {:find ['?sort-default '?e] + :where ['[?e :sales-refund/date ?sort-default]]}}))] + + (cond->> (query2 query) + true (apply-sort-3 query-params) + true (apply-pagination query-params)))) + +(defn hydrate-results [ids db _] + (let [results (->> (pull-many db default-read ids) + (group-by :db/id)) + refunds (->> ids + (map results) + (map first) + (mapv <-datomic) + )] + refunds)) + +(defn fetch-page [_ args] + (let [db (dc/db conn) + {ids-to-retrieve :ids matching-count :count} (fetch-ids db args)] + + [(->> (hydrate-results ids-to-retrieve db args)) + matching-count])) + +(def grid-page {:id "refund-table" + :nav (com/main-aside-nav) + :page-specific-nav filters + :id-fn :db/id + :fetch-page fetch-page + :oob-render + (fn [_ params] + [(assoc-in (date-range-field* params) [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 + :pos-refunds)} + "Refunds"]] + :title "Refunds" + :entity-name "Refund" + :route :pos-refund-table + :action-buttons (fn [_ args]) + :row-buttons (fn [_ e]) + :headers [{:key "client" + :name "Client" + :sort-key "client" + :hide? (fn [args] + (= (count (:clients args)) 1)) + :render #(-> % :sales-refund/client :client/code)} + {:key "date" + :name "Date" + :sort-key "date" + :render #(atime/unparse-local (:sales-refund/date %) atime/standard-time)} + {:key "total" + :name "Total" + :sort-key "total" + :render #(some->> % :sales-refund/total (format "$%.2f"))} + {:key "type" + :name "Type" + :sort-key "type" + :render :sales-refund/type} + {:key "fee" + :name "Fee" + :sort-key "fee" + :render #(some->> % :sales-refund/fee (format "$%.2f"))}]}) + +(def row* (partial helper/row* grid-page)) +(def table* (partial helper/table* grid-page)) +(def table (partial helper/table grid-page)) +(def page (partial helper/page grid-page)) + +(def key->handler + {:pos-refunds (wrap-client-redirect-unauthenticated (wrap-secure page)) + :pos-refund-table (wrap-client-redirect-unauthenticated (wrap-secure table))}) diff --git a/src/clj/auto_ap/ssr/pos/sales_orders.clj b/src/clj/auto_ap/ssr/pos/sales_orders.clj index 77391e53..3aaaf682 100644 --- a/src/clj/auto_ap/ssr/pos/sales_orders.clj +++ b/src/clj/auto_ap/ssr/pos/sales_orders.clj @@ -6,6 +6,8 @@ [auto-ap.ssr-routes :as ssr-routes] [auto-ap.ssr.components :as com] [auto-ap.ssr.grid-page-helper :as helper] + [auto-ap.ssr.pos.common + :refer [date-range-field* processor-field* total-field*]] [auto-ap.ssr.svg :as svg] [auto-ap.time :as atime] [bidi.bidi :as bidi])) @@ -15,67 +17,18 @@ ;; always should be fast ;; make params parsing composable -(defn date-range-field* [params] - [:div#date-range {} - (com/field {:label "Date Range"} - [:div.space-y-4 - [:div - (com/button-group {:name "date-range"} - (com/button-group-button {:size :small :value "all" :hx-trigger "click"} "All") - (com/button-group-button {:size :small :value "week" :hx-trigger "click"} "Week") - (com/button-group-button {:size :small :value "month" :hx-trigger "click"} "Month") - (com/button-group-button {:size :small :value "year" :hx-trigger "click"} "Year")) - ] - [:div.flex.space-x-1.items-baseline - (com/date-input {:name "start-date" - :value (some-> params - :parsed-query-params - :start-date - (atime/parse atime/normal-date) - (atime/unparse-local - atime/normal-date)) - :placeholder "Date" - :size :small}) - - (com/date-input {:name "end-date" - :value (some-> params - :parsed-query-params - :end-date - (atime/parse atime/normal-date) - (atime/unparse-local - atime/normal-date)) - :placeholder "Date" - :size :small})]] - )]) + (defn filters [params] - [:form {"hx-trigger" "change delay:500ms, keyup changed from:.hot-filter delay:1000ms" - "hx-get" (bidi/path-for ssr-routes/only-routes + [:form {"hx-trigger" "change delay:500ms, keyup changed from:.hot-filter delay:1000ms" + "hx-get" (bidi/path-for ssr-routes/only-routes :pos-sales-table) - "hx-target" "#sales-table" - "hx-indicator" "#sales-table" + "hx-target" "#sales-table" + "hx-indicator" "#sales-table" #_#_:hx-disabled-elt "find fieldset"} [:fieldset.space-y-6 (date-range-field* params) - [:div - (com/field {:label "Total"} - [:div.flex.space-x-4.items-baseline - (com/money-input {:name "total-gte" - :id "total-gte" - :hx-preserve "true" - :class "hot-filter" - :value (:total-gte (:parsed-query-params params)) - :placeholder "0.01" - :size :small}) - [:div.align-baseline - "to"] - (com/money-input {:name "total-lte" - :hx-preserve "true" - :id "total-lte" - :class "hot-filter" - :value (:total-lte (:parsed-query-params params)) - :placeholder "9999.34" - :size :small})])] + [:div (total-field* params)] [:div (com/field {:label "Payment Method"} (com/radio {:size :small @@ -92,27 +45,7 @@ :content "Other"} ]}))] [:div - - (com/field {:label "Processor"} - (com/radio {:size :small - :name "processor" - :options [{:value "" - :content "All"} - {:value "square" - :content [:div.flex.space-x-2 [:img.align-center {:src "/img/square.png" :style {:width "16px" :height "16px"}}] [:div "Square"]]} - {:value "doordash" - :content [:div.flex.space-x-2 [:img.align-center {:src "/img/doordash.png" :style {:width "16px" :height "16px"}}] [:div "Doordash"]]} - {:value "uber-eats" - :content [:div.flex.space-x-2 [:img.align-center {:src "/img/ubereats.png" :style {:width "16px" :height "16px"}}] [:div "Uber eats"]]} - {:value "grubhub" - :content [:div.flex.space-x-2 [:img.align-center {:src "/img/grubhub.png" :style {:width "16px" :height "16px"}}] [:div "Grubhub"]]} - {:value "koala" - :content [:div.flex.space-x-2 [:img.align-center {:src "/img/koala.png" :style {:width "16px" :height "16px"}}] [:div "Koala"]]} - {:value "ezcater" - :content [:div.flex.space-x-2 [:img.align-center {:src "/img/ezcater.png" :style {:width "16px" :height "16px"}}] [:div "EZCater"]]} - {:value "na" - :content "No Processor"} - ]}))] + (processor-field* params)] [:div (com/field {:label "Category"} diff --git a/src/clj/auto_ap/ssr/pos/tenders.clj b/src/clj/auto_ap/ssr/pos/tenders.clj new file mode 100644 index 00000000..1d6de99e --- /dev/null +++ b/src/clj/auto_ap/ssr/pos/tenders.clj @@ -0,0 +1,204 @@ +(ns auto-ap.ssr.pos.tenders + (:require + [auto-ap.datomic + :refer [add-sorter-fields + apply-pagination + apply-sort-3 + conn + merge-query + pull-many + query2]] + [auto-ap.graphql.utils :refer [extract-client-ids]] + [auto-ap.routes.utils + :refer [wrap-client-redirect-unauthenticated wrap-secure]] + [auto-ap.ssr.pos.common :refer [date-range-field* processor-field* total-field*]] + [auto-ap.ssr-routes :as ssr-routes] + [auto-ap.ssr.components :as com] + [auto-ap.ssr.grid-page-helper :as helper] + [auto-ap.ssr.svg :as svg] + [auto-ap.time :as atime] + [bidi.bidi :as bidi] + [clj-time.coerce :as c] + [datomic.api :as dc] + [clojure.set :as set])) + +;; TODO refunds +;; always should be fast +;; make params parsing composable + +(defn filters [params] + [:form {"hx-trigger" "change delay:500ms, keyup changed from:.hot-filter delay:1000ms" + "hx-get" (bidi/path-for ssr-routes/only-routes + :pos-tender-table) + "hx-target" "#tender-table" + "hx-indicator" "#tender-table" + #_#_:hx-disabled-elt "find fieldset"} + + [:fieldset.space-y-6 + (date-range-field* params) + (processor-field* params) + (total-field* params)]]) + +(defn <-datomic [result] + (let [expected-deposit (some-> (:expected-deposit/_charges result) + first + (update :expected-deposit/date c/from-date))] + (cond-> result + true (update :charge/date c/from-date) + true (update :charge/processor :db/ident) + expected-deposit (assoc :expected-deposit expected-deposit)))) + +(def default-read '[* + {:charge/client [:client/name :db/id :client/code] + :charge/processor [:db/ident] + :expected-deposit/_charges [:expected-deposit/date :db/id]}]) + +(defn fetch-ids [db args] + (let [query-params (:parsed-query-params args) + valid-clients (extract-client-ids (:clients args) + (:client args) + (:client-id query-params) + (when (:client-code query-params) + [:client/code (:client-code query-params)])) + valid-clients (->> valid-clients + (take 10) + set) + _ (println "valid clients" valid-clients) + start-date (some-> args + :parsed-query-params + :start-date + (atime/parse atime/normal-date)) + end-date (some-> args + :parsed-query-params + :end-date + (atime/parse atime/normal-date)) + total-gte (some-> args :parsed-query-params :total-gte not-empty (#(if (string? %) (Double/parseDouble %) (double %)))) + total-lte (some-> args :parsed-query-params :total-lte not-empty (#(if (string? %) (Double/parseDouble %) (double %)))) + processor (some-> query-params :processor (#(keyword "ccp-processor" (name %)))) + query (cond-> {:query {:find [] + :in ['$ '[?clients ?start-date ?end-date]] + :where '[[(iol-ion.query/scan-charges $ ?clients ?start-date ?end-date) [[?e _ ?sort-default] ...]]]} + :args [db [valid-clients + (some-> start-date c/to-date) + (some-> end-date c/to-date )]]} + (:sort query-params) (add-sorter-fields {"client" ['[?e :charge/client ?c] + '[?c :client/name ?sort-client]] + "date" ['[?e :charge/date ?sort-date]] + "total" ['[?e :charge/total ?sort-total]] + "tip" ['[?e :charge/tip ?sort-tip]] + "processor" ['[?e :charge/processor ?p] + '[?p :db/ident ?p2] + '[(name ?p2) ?sort-processor]]} + query-params) + + (:exact-match-id query-params) + (merge-query {:query {:in ['?e] + :where []} + :args [(:exact-match-id query-params)]}) + + total-gte + (merge-query {:query {:in ['?total-gte] + :where ['[?e :charge/total ?a] + '[(>= ?a ?total-gte)]]} + :args [total-gte]}) + + total-lte + (merge-query {:query {:in ['?total-lte] + :where ['[?e :charge/total ?a] + '[(<= ?a ?total-lte)]]} + :args [total-lte]}) + + processor + (merge-query {:query {:in '[?processor] + :where ['[?e :charge/processor ?processor]]} + :args [processor]}) + + + true + (merge-query {:query {:find ['?sort-default '?e]}}))] + (cond->> (query2 query) + true (apply-sort-3 query-params) + true (apply-pagination query-params)))) + +(defn hydrate-results [ids db _] + (let [results (->> (pull-many db default-read ids) + (group-by :db/id)) + charges (->> ids + (map results) + (map first) + (mapv <-datomic) + )] + charges)) + +(defn fetch-page [_ args] + (let [db (dc/db conn) + {ids-to-retrieve :ids matching-count :count} (fetch-ids db args)] + + [(->> (hydrate-results ids-to-retrieve db args)) + matching-count])) + +(def grid-page {:id "tender-table" + :nav (com/main-aside-nav) + :page-specific-nav filters + :id-fn :db/id + :fetch-page fetch-page + :oob-render + (fn [_ params] + [(assoc-in (date-range-field* params) [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 + :pos-tenders)} + "Tenders"]] + :title "Tenders" + :entity-name "Tender" + :route :pos-tender-table + :action-buttons (fn [_ args]) + :row-buttons (fn [_ e] + (when (:charge/reference-link e) + [(com/a-icon-button {:href (:charge/reference-link e)} + svg/external-link)])) + :headers [{:key "client" + :name "Client" + :sort-key "client" + :hide? (fn [args] + (= (count (:clients args)) 1)) + :render #(-> % :charge/client :client/code)} + {:key "date" + :name "Date" + :sort-key "date" + :render #(atime/unparse-local (:charge/date %) atime/standard-time)} + {:key "total" + :name "Total" + :sort-key "total" + :render #(some->> % :charge/total (format "$%.2f"))} + {:key "processor" + :name "Processor" + :sort-key "processor" + :render (fn [sales-order] + (when (:charge/processor sales-order) + (com/pill {:color :primary } + (name (:charge/processor sales-order)))))} + {:key "tip" + :name "Tip" + :sort-key "tip" + :render #(some->> % :charge/tip (format "$%.2f"))} + {:key "links" + :name "Links" + :render (fn [entity] + (when-let [expected-deposit-id (some->> entity :expected-deposit :db/id)] + [:a {:href (str (bidi/path-for ssr-routes/only-routes + :pos-expected-deposits) + "?exact-match-id=" expected-deposit-id)} + (com/pill {:color :secondary} "expected deposit")]))}]}) + +(def row* (partial helper/row* grid-page)) +(def table* (partial helper/table* grid-page)) +(def table (partial helper/table grid-page)) +(def page (partial helper/page grid-page)) + +(def key->handler + {:pos-tenders (wrap-client-redirect-unauthenticated (wrap-secure page)) + :pos-tender-table (wrap-client-redirect-unauthenticated (wrap-secure table))}) diff --git a/src/cljc/auto_ap/ssr_routes.cljc b/src/cljc/auto_ap/ssr_routes.cljc index c6698efc..79f6edce 100644 --- a/src/cljc/auto_ap/ssr_routes.cljc +++ b/src/cljc/auto_ap/ssr_routes.cljc @@ -20,7 +20,16 @@ ["/rows/" [#"\d+" :after]] {:get :transaction-insight-rows} ["/explain/" [#"\d+" :transaction-id]] {:get :transaction-insight-explain}}} "pos" {"/sales" {"" {:get :pos-sales} - "/table" {:get :pos-sales-table}}} + "/table" {:get :pos-sales-table}} + "/expected-deposit" {"" {:get :pos-expected-deposits} + "/table" {:get :pos-expected-deposit-table}} + "/tenders" {"" {:get :pos-tenders} + "/table" {:get :pos-tender-table}} + "/refunds" {"" {:get :pos-refunds} + "/table" {:get :pos-refund-table}} + "/cash-drawer-shifts" {"" {:get :pos-cash-drawer-shifts} + "/table" {:get :pos-cash-drawer-shift-table}}} + "company" {"" :company "/dropdown" :company-dropdown-search-results "/active" {:put :active-client}