Links for ledger, and bank account picker
This commit is contained in:
File diff suppressed because one or more lines are too long
@@ -1,7 +1,6 @@
|
||||
(ns auto-ap.ssr.company-dropdown
|
||||
(:require [auto-ap.datomic :refer [conn pull-many]]
|
||||
[auto-ap.graphql.utils :refer [cleanse-query]]
|
||||
[auto-ap.logging :as alog]
|
||||
[auto-ap.solr :as solr]
|
||||
[auto-ap.ssr-routes :as ssr-routes]
|
||||
[auto-ap.ssr.hx :as hx]
|
||||
@@ -69,7 +68,6 @@
|
||||
(dropdown-search-results* {:options (get-clients identity (get (:query-params request) "search-text"))})))
|
||||
|
||||
(defn dropdown [{:keys [client-selection client identity clients]}]
|
||||
(alog/peek ::clients clients)
|
||||
[:div#company-dropdown
|
||||
[:script
|
||||
(hiccup/raw
|
||||
|
||||
@@ -4,8 +4,7 @@
|
||||
[auto-ap.ssr.svg :as svg]))
|
||||
|
||||
(defn link-dropdown [links]
|
||||
(if (> (count links) 0)
|
||||
|
||||
(when (> (count links) 0)
|
||||
[:div {:x-data (hx/json {:popper nil
|
||||
:show false})
|
||||
"@click.outside" "show=false"
|
||||
@@ -17,7 +16,7 @@
|
||||
(com/badge {:color "blue"} (count links)))
|
||||
[:div.divide-y.divide-gray-200.bg-white.rounded-lg.shadow.z-50 (hx/alpine-appear {:x-ref "tooltip" :x-show "show" :data-key "show"})
|
||||
[:div {:class "p-3 overflow-y-auto text-sm text-gray-700 dark:text-gray-200"}
|
||||
[:div.flex.flex-col.gap-y-2
|
||||
[:div.flex.flex-col.gap-y-2 {:class "max-w-[24em]"}
|
||||
(for [l links]
|
||||
[:div.flex-initial
|
||||
[:a {:href (:link l) :target "_blank"}
|
||||
|
||||
@@ -1,54 +1,44 @@
|
||||
(ns auto-ap.ssr.ledger
|
||||
(:require [auto-ap.datomic
|
||||
(:require [auto-ap.client-routes :as client-routes]
|
||||
[auto-ap.datomic
|
||||
:refer [add-sorter-fields apply-pagination apply-sort-3
|
||||
audit-transact conn merge-query observable-query
|
||||
pull-many]]
|
||||
[auto-ap.datomic.accounts :as d-accounts]
|
||||
[auto-ap.datomic.bank-accounts :as d-bank-accounts]
|
||||
[auto-ap.datomic.invoices :as d-invoices]
|
||||
[auto-ap.graphql.checks :as gq-checks :refer [base-payment
|
||||
invoice-payments
|
||||
print-checks-internal
|
||||
validate-belonging]]
|
||||
[auto-ap.graphql.checks :as gq-checks]
|
||||
[auto-ap.graphql.utils :refer [assert-can-see-client
|
||||
assert-not-locked exception->4xx
|
||||
assert-not-locked
|
||||
exception->notification
|
||||
extract-client-ids notify-if-locked]]
|
||||
[auto-ap.logging :as alog]
|
||||
[auto-ap.permissions :refer [can?]]
|
||||
[auto-ap.query-params :refer [wrap-copy-qp-pqp]]
|
||||
[auto-ap.routes.invoice :as invoice-route]
|
||||
[auto-ap.routes.ledger :as route]
|
||||
[auto-ap.routes.payments :as payment-route]
|
||||
[auto-ap.routes.utils
|
||||
:refer [wrap-client-redirect-unauthenticated]]
|
||||
[auto-ap.solr :as solr]
|
||||
[auto-ap.ssr-routes :as ssr-routes]
|
||||
[auto-ap.ssr.components :as com]
|
||||
[auto-ap.ssr.components.multi-modal :as mm]
|
||||
[auto-ap.ssr.form-cursor :as fc]
|
||||
[auto-ap.ssr.components.link-dropdown :refer [link-dropdown]]
|
||||
[auto-ap.ssr.grid-page-helper :as helper :refer [wrap-apply-sort]]
|
||||
[auto-ap.ssr.hiccup-helper :as hh]
|
||||
[auto-ap.ssr.hx :as hx]
|
||||
[auto-ap.ssr.pos.common :refer [date-range-field*]]
|
||||
[auto-ap.ssr.svg :as svg]
|
||||
[auto-ap.ssr.utils
|
||||
:refer [apply-middleware-to-all-handlers assert-schema
|
||||
clj-date-schema dissoc-nil-transformer entity-id
|
||||
html-response main-transformer modal-response money
|
||||
ref->enum-schema round-money strip
|
||||
:refer [apply-middleware-to-all-handlers clj-date-schema
|
||||
dissoc-nil-transformer entity-id html-response
|
||||
main-transformer modal-response ref->enum-schema strip
|
||||
wrap-implied-route-param wrap-merge-prior-hx
|
||||
wrap-schema-enforce]]
|
||||
[auto-ap.time :as atime]
|
||||
[auto-ap.utils :refer [by dollars-0?]]
|
||||
[auto-ap.utils :refer [dollars-0?]]
|
||||
[bidi.bidi :as bidi]
|
||||
[clj-time.coerce :as coerce]
|
||||
[clj-time.core :as time]
|
||||
[clojure.string :as str]
|
||||
[datomic.api :as dc]
|
||||
[hiccup.util :as hu]
|
||||
[malli.core :as mc]
|
||||
[malli.transform :as mt]
|
||||
[malli.util :as mut]))
|
||||
[malli.transform :as mt]))
|
||||
|
||||
|
||||
|
||||
@@ -66,6 +56,30 @@
|
||||
svg/x)]])]
|
||||
[:div {:id "exact-match-id-tag"}]))
|
||||
|
||||
(defn bank-account-filter* [request]
|
||||
[:div {:hx-trigger "clientSelected from:body"
|
||||
:hx-get (bidi.bidi/path-for ssr-routes/only-routes ::route/bank-account-filter)
|
||||
:hx-target "this"
|
||||
:hx-swap "outerHTML"}
|
||||
(when (:client request)
|
||||
(let [bank-account-belongs-to-client? (get (set (map :db/id (:client/bank-accounts (:client request))))
|
||||
(:db/id (:bank-account (:query-params request))))]
|
||||
(com/field {:label "Bank Account"}
|
||||
(com/radio-card {:size :small
|
||||
:name "bank-account"
|
||||
:value (or (when bank-account-belongs-to-client?
|
||||
(:db/id (:bank-account (:query-params request))))
|
||||
"")
|
||||
:options
|
||||
(into [{:value ""
|
||||
:content "All"}]
|
||||
(for [ba (:client/bank-accounts (:client request))]
|
||||
{:value (:db/id ba)
|
||||
:content (:bank-account/name ba)}))}))))])
|
||||
|
||||
(defn bank-account-filter [request]
|
||||
(html-response (bank-account-filter* request)))
|
||||
|
||||
(defn filters [request]
|
||||
[:form#ledger-filters {"hx-trigger" "change delay:500ms, keyup changed from:.hot-filter delay:1000ms"
|
||||
"hx-get" (bidi/path-for ssr-routes/only-routes
|
||||
@@ -91,6 +105,9 @@
|
||||
:value-fn :db/id
|
||||
:content-fn #(:account/name (d-accounts/clientize (dc/pull (dc/db conn) d-accounts/default-read (:db/id %))
|
||||
(:db/id (:client request))))}))
|
||||
|
||||
(bank-account-filter* request)
|
||||
|
||||
(date-range-field* request)
|
||||
(com/field {:label "Invoice #"}
|
||||
(com/text-input {:name "invoice-number"
|
||||
@@ -170,7 +187,7 @@
|
||||
|
||||
(or (seq (:numeric-code args))
|
||||
(:account args)
|
||||
(:bank-account-id args)
|
||||
(:db/id (:bank-account args))
|
||||
(not-empty (:location args)))
|
||||
(merge-query {:query {:where ['[?e :journal-entry/line-items ?li]]}})
|
||||
|
||||
@@ -203,10 +220,10 @@
|
||||
'[(<= ?a ?amount-lte)]]}
|
||||
:args [(:amount-lte args)]})
|
||||
|
||||
(:bank-account-id args)
|
||||
(:db/id (:bank-account args))
|
||||
(merge-query {:query {:in ['?a]
|
||||
:where ['[?li :journal-entry-line/account ?a]]}
|
||||
:args [(:bank-account-id args)]})
|
||||
:args [(:db/id (:bank-account args))]})
|
||||
|
||||
(:account-id args)
|
||||
(merge-query {:query {:in ['?a2]
|
||||
@@ -238,24 +255,28 @@
|
||||
(merge-query {:query {:find ['?sort-default '?e]}})))]
|
||||
|
||||
(->> (observable-query query)
|
||||
(apply-sort-3 (assoc query-params :default-asc? false))
|
||||
(apply-sort-3 (assoc query-params :default-asc? true))
|
||||
(apply-pagination query-params))))
|
||||
|
||||
(def default-read
|
||||
'[:journal-entry/amount
|
||||
(def default-read
|
||||
'[:journal-entry/amount
|
||||
:journal-entry/alternate-description
|
||||
:db/id
|
||||
[:journal-entry/date :xform clj-time.coerce/from-date]
|
||||
{
|
||||
:journal-entry/vendor [:vendor/name :db/id]
|
||||
[:journal-entry/date :xform clj-time.coerce/from-date]
|
||||
{:journal-entry/vendor [:vendor/name :db/id]
|
||||
:journal-entry/original-entity [:invoice/invoice-number
|
||||
:invoice/source-url
|
||||
:transaction/description-original :db/id]
|
||||
:journal-entry/client [:client/name :client/code :db/id]
|
||||
:journal-entry/line-items [:journal-entry-line/debit
|
||||
:journal-entry-line/location
|
||||
:journal-entry-line/credit
|
||||
{:journal-entry-line/account [:account/name :db/id :account/numeric-code
|
||||
{[ :account/type :xform iol-ion.query/ident] [:db/ident :db/id]}
|
||||
:bank-account/name :bank-account/numeric-code
|
||||
{[:account/type :xform iol-ion.query/ident] [:db/ident :db/id]}
|
||||
{:account/client-overrides [:account-client-override/name
|
||||
{:account-client-override/client [:db/id]}]}
|
||||
{[ :bank-account/type :xform iol-ion.query/ident]
|
||||
{[:bank-account/type :xform iol-ion.query/ident]
|
||||
[:db/ident :db/id]}]}]}])
|
||||
|
||||
(defn hydrate-results [ids db _]
|
||||
@@ -311,6 +332,7 @@
|
||||
[:amount-gte {:optional true} [:maybe :double]]
|
||||
[:amount-lte {:optional true} [:maybe :double]]
|
||||
[:vendor {:optional true :default nil} [:maybe [:entity-map {:pull [:db/id :vendor/name]}]]]
|
||||
[:bank-account {:optional true :default nil} [:maybe [:entity-map {:pull [:db/id :bank-account/name]}]]]
|
||||
[:account {:optional true :default nil} [:maybe [:entity-map {:pull [:db/id :account/name]}]]]
|
||||
[:check-number {:optional true} [:maybe [:string {:decode/string strip}]]]
|
||||
[:invoice-number {:optional true} [:maybe [:string {:decode/string strip}]]]
|
||||
@@ -353,13 +375,14 @@
|
||||
|
||||
(for [jel lines
|
||||
:let [account (d-accounts/clientize (:journal-entry-line/account jel) (:db/id client))
|
||||
account-name (:account/name account)]]
|
||||
account-name (or (:account/name account)
|
||||
(:bank-account/name (:journal-entry-line/account jel)))]]
|
||||
(list
|
||||
|
||||
(if account-name
|
||||
[:div.text-left
|
||||
(:journal-entry-line/location jel) ": "
|
||||
(:account/numeric-code account)
|
||||
(or (:account/numeric-code account) (:bank-account/numeric-code account))
|
||||
" - " account-name]
|
||||
[:div.text-left (com/pill {:color :yellow} "Unassigned")])
|
||||
[:div.text-right (format "$%,.2f" (key jel))]))
|
||||
@@ -439,7 +462,8 @@
|
||||
{:key "vendor"
|
||||
:name "Vendor"
|
||||
:sort-key "vendor"
|
||||
:render #(-> % :journal-entry/vendor :vendor/name)}
|
||||
:render (fn [e] (or (-> e :journal-entry/vendor :vendor/name)
|
||||
[:span.italic.text-gray-400 (-> e :journal-entry/alternate-description)]))}
|
||||
{:key "date"
|
||||
:sort-key "date"
|
||||
:name "Date"
|
||||
@@ -457,37 +481,32 @@
|
||||
:sort-key "credit"
|
||||
:class "text-right"
|
||||
:render (partial render-lines :journal-entry-line/credit)}
|
||||
#_{:key "links"
|
||||
{:key "links"
|
||||
:name "Links"
|
||||
:show-starting "lg"
|
||||
:class "w-8"
|
||||
:render (fn [i]
|
||||
(link-dropdown
|
||||
(concat (->> i
|
||||
:invoice/payments
|
||||
(map :invoice-payment/payment)
|
||||
(filter (fn [p]
|
||||
(not= :payment-status/voided
|
||||
(:payment/status p))))
|
||||
(mapcat (fn [p]
|
||||
(cond-> [{:link (hu/url (bidi/path-for ssr-routes/only-routes
|
||||
::payment-route/all-page)
|
||||
{:exact-match-id (:db/id p)})
|
||||
:content (str (format "$%,.2f" (:payment/amount p))
|
||||
(some-> (:payment/date p) coerce/to-date-time (atime/unparse-local atime/normal-date) (#(str " payment on " %))))}]
|
||||
(:payment/transaction p) (conj {:link (hu/url (bidi/path-for client-routes/routes :transactions)
|
||||
{:exact-match-id (:db/id (first (:payment/transaction p)))})
|
||||
:color :secondary
|
||||
:content "Transaction"})))))
|
||||
(when (:invoice/journal-entry i)
|
||||
[{:link (hu/url (bidi/path-for client-routes/routes :ledger)
|
||||
{:exact-match-id (:db/id (first (:invoice/journal-entry i)))})
|
||||
:color :yellow
|
||||
:content "Ledger entry"}])
|
||||
(when (:invoice/source-url i)
|
||||
[{:link (:invoice/source-url i)
|
||||
:color :secondary
|
||||
:content "File"}]))))}]}))
|
||||
(cond-> []
|
||||
(-> i :journal-entry/original-entity :invoice/invoice-number)
|
||||
(conj
|
||||
{:link (hu/url (bidi/path-for ssr-routes/only-routes
|
||||
::invoice-route/all-page)
|
||||
{:exact-match-id (:db/id (:journal-entry/original-entity i))})
|
||||
:color :primary
|
||||
:content (format "Invoice '%s'" (-> i :journal-entry/original-entity :invoice/invoice-number))})
|
||||
(-> i :journal-entry/original-entity :invoice/source-url)
|
||||
{:link (-> i :journal-entry/original-entity :invoice/source-url)
|
||||
:color :secondary
|
||||
:content (str "File")}
|
||||
|
||||
(-> i :journal-entry/original-entity :transaction/description-original)
|
||||
(conj
|
||||
{:link (hu/url (bidi/path-for client-routes/routes
|
||||
:transactions)
|
||||
{:exact-match-id (:db/id (:journal-entry/original-entity i))})
|
||||
:color :primary
|
||||
:content (format "Transaction '%s'" (-> i :journal-entry/original-entity :transaction/description-original))}))))}]}))
|
||||
|
||||
(def row* (partial helper/row* grid-page))
|
||||
|
||||
@@ -649,8 +668,15 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
(defn wrap-ensure-bank-account-belongs [handler]
|
||||
(fn [{:keys [query-params client] :as request}]
|
||||
(let [bank-account-belongs? (get (set (map :db/id (:client/bank-accounts client)))
|
||||
(:db/id (:bank-account query-params)))]
|
||||
(handler (cond-> request
|
||||
(not client)
|
||||
(update :query-params dissoc :bank-account)
|
||||
(not bank-account-belongs?)
|
||||
(update :query-params dissoc :bank-account))))))
|
||||
|
||||
(defn wrap-status-from-source [handler]
|
||||
(fn [{:keys [matched-current-page-route] :as request}]
|
||||
@@ -662,21 +688,19 @@
|
||||
(handler request))))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
(def key->handler
|
||||
(apply-middleware-to-all-handlers
|
||||
(->
|
||||
{::route/all-page (-> (helper/page-route grid-page :parse-query-params? false)
|
||||
(wrap-implied-route-param :status nil))
|
||||
::route/table (helper/table-route grid-page :parse-query-params? false)})
|
||||
::route/table (helper/table-route grid-page :parse-query-params? false)
|
||||
::route/bank-account-filter bank-account-filter})
|
||||
(fn [h]
|
||||
(-> h
|
||||
(wrap-copy-qp-pqp)
|
||||
(wrap-status-from-source)
|
||||
(wrap-apply-sort grid-page)
|
||||
(wrap-ensure-bank-account-belongs)
|
||||
(wrap-merge-prior-hx)
|
||||
(wrap-schema-enforce :query-schema query-schema)
|
||||
(wrap-schema-enforce :hx-schema query-schema)
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
(ns auto-ap.routes.ledger)
|
||||
|
||||
(def routes {"" {:get ::all-page}
|
||||
"/table" ::table })
|
||||
"/table" ::table
|
||||
"/bank-account-filter" ::bank-account-filter})
|
||||
Reference in New Issue
Block a user