External ledger
This commit is contained in:
File diff suppressed because one or more lines are too long
@@ -94,7 +94,7 @@
|
|||||||
"sales"
|
"sales"
|
||||||
(#{::payment-routes/all-page ::payment-routes/pending-page ::payment-routes/cleared-page ::payment-routes/voided-page} (:matched-route request))
|
(#{::payment-routes/all-page ::payment-routes/pending-page ::payment-routes/cleared-page ::payment-routes/voided-page} (:matched-route request))
|
||||||
"payments"
|
"payments"
|
||||||
(#{::ledger-routes/all-page} (:matched-route request))
|
(#{::ledger-routes/all-page ::ledger-routes/external-page} (:matched-route request))
|
||||||
"ledger"
|
"ledger"
|
||||||
:else
|
:else
|
||||||
nil)]
|
nil)]
|
||||||
@@ -285,6 +285,14 @@
|
|||||||
(tags/pill- {:color :secondary} "WIP")])
|
(tags/pill- {:color :secondary} "WIP")])
|
||||||
(menu-button- {:href (bidi/path-for client-routes/routes
|
(menu-button- {:href (bidi/path-for client-routes/routes
|
||||||
:ledger)} "Register"))
|
:ledger)} "Register"))
|
||||||
|
(menu-button- {:href (hu/url (bidi/path-for ssr-routes/only-routes
|
||||||
|
::ledger-routes/external-page)
|
||||||
|
{:date-range "month"})
|
||||||
|
:active? (= ::ledger-routes/external-page (:matched-route request))
|
||||||
|
:hx-boost "true"}
|
||||||
|
[:div.flex.gap-2
|
||||||
|
"External Register"
|
||||||
|
(tags/pill- {:color :secondary} "WIP")])
|
||||||
(when (is-admin? (:identity request))
|
(when (is-admin? (:identity request))
|
||||||
(menu-button- {:href (bidi/path-for client-routes/routes
|
(menu-button- {:href (bidi/path-for client-routes/routes
|
||||||
:ledger)} "Old Register")
|
:ledger)} "Old Register")
|
||||||
|
|||||||
@@ -173,6 +173,8 @@
|
|||||||
(merge-query {:query {:in ['?source]
|
(merge-query {:query {:in ['?source]
|
||||||
:where ['[?e :journal-entry/source ?source]]}
|
:where ['[?e :journal-entry/source ?source]]}
|
||||||
:args [(:source args)]})
|
:args [(:source args)]})
|
||||||
|
(:external? route-params)
|
||||||
|
(merge-query {:query { :where ['[?e :journal-entry/external-id]]} })
|
||||||
|
|
||||||
(:vendor args)
|
(:vendor args)
|
||||||
(merge-query {:query {:in ['?vendor-id]
|
(merge-query {:query {:in ['?vendor-id]
|
||||||
@@ -261,6 +263,8 @@
|
|||||||
(def default-read
|
(def default-read
|
||||||
'[:journal-entry/amount
|
'[:journal-entry/amount
|
||||||
:journal-entry/alternate-description
|
:journal-entry/alternate-description
|
||||||
|
:journal-entry/source
|
||||||
|
:journal-entry/external-id
|
||||||
:db/id
|
:db/id
|
||||||
[:journal-entry/date :xform clj-time.coerce/from-date]
|
[:journal-entry/date :xform clj-time.coerce/from-date]
|
||||||
{:journal-entry/vendor [:vendor/name :db/id]
|
{:journal-entry/vendor [:vendor/name :db/id]
|
||||||
@@ -448,8 +452,14 @@
|
|||||||
:entity-name "register"
|
:entity-name "register"
|
||||||
:route ::route/table
|
:route ::route/table
|
||||||
:break-table (fn [request entity]
|
:break-table (fn [request entity]
|
||||||
(when (= (-> request :query-params :sort first :name) "Vendor")
|
(cond
|
||||||
(-> entity :journal-entry/vendor :vendor/name)))
|
(= (-> request :query-params :sort first :name) "Vendor")
|
||||||
|
(-> entity :journal-entry/vendor :vendor/name)
|
||||||
|
|
||||||
|
(= (-> request :query-params :sort first :name) "Source")
|
||||||
|
(-> entity :journal-entry/source)
|
||||||
|
|
||||||
|
:else nil))
|
||||||
:headers [{:key "client"
|
:headers [{:key "client"
|
||||||
:name "Client"
|
:name "Client"
|
||||||
:sort-key "client"
|
:sort-key "client"
|
||||||
@@ -459,11 +469,25 @@
|
|||||||
:render (fn [x] [:div.flex.items-center.gap-2 (-> x :invoice/client :client/name)
|
:render (fn [x] [:div.flex.items-center.gap-2 (-> x :invoice/client :client/name)
|
||||||
(map #(com/pill {:color :primary} (-> % :invoice-expense-account/location))
|
(map #(com/pill {:color :primary} (-> % :invoice-expense-account/location))
|
||||||
(:invoice/expense-accounts x)) ])}
|
(:invoice/expense-accounts x)) ])}
|
||||||
|
|
||||||
{:key "vendor"
|
{:key "vendor"
|
||||||
:name "Vendor"
|
:name "Vendor"
|
||||||
:sort-key "vendor"
|
:sort-key "vendor"
|
||||||
:render (fn [e] (or (-> e :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)]))}
|
[:span.italic.text-gray-400 (-> e :journal-entry/alternate-description)]))}
|
||||||
|
{:key "source"
|
||||||
|
:name "Source"
|
||||||
|
:sort-key "source"
|
||||||
|
:hide? (fn [args]
|
||||||
|
(not (:external? (:route-params args))))
|
||||||
|
:render :journal-entry/source}
|
||||||
|
{:key "external-id"
|
||||||
|
:name "External Id"
|
||||||
|
:sort-key "external-id"
|
||||||
|
:class "max-w-[12rem]"
|
||||||
|
:hide? (fn [args]
|
||||||
|
(not (:external? (:route-params args))))
|
||||||
|
:render (fn [x] [:p.truncate ( :journal-entry/external-id x)])}
|
||||||
{:key "date"
|
{:key "date"
|
||||||
:sort-key "date"
|
:sort-key "date"
|
||||||
:name "Date"
|
:name "Date"
|
||||||
@@ -510,40 +534,6 @@
|
|||||||
|
|
||||||
(def row* (partial helper/row* grid-page))
|
(def row* (partial helper/row* grid-page))
|
||||||
|
|
||||||
(defn unvoid-invoice [{:as request :keys [identity entity]}]
|
|
||||||
(let [invoice entity
|
|
||||||
id (:db/id entity)
|
|
||||||
_ (assert-can-see-client identity (:db/id (:invoice/client invoice)))
|
|
||||||
_ (assert-not-locked (:db/id (:invoice/client invoice)) (:invoice/date invoice))
|
|
||||||
history (dc/history (dc/db conn))
|
|
||||||
txs (dc/q {:find ['?tx '?e '?original-status '?original-outstanding '?total '?ea '?ea-amount]
|
|
||||||
:where ['[?e :invoice/status :invoice-status/voided ?tx true]
|
|
||||||
'[?e :invoice/status ?original-status ?tx false]
|
|
||||||
'[?e :invoice/outstanding-balance ?original-outstanding ?tx false]
|
|
||||||
'[?e :invoice/total ?total ?tx false]
|
|
||||||
'[?ea :invoice-expense-account/amount ?ea-amount ?tx false]]
|
|
||||||
:in ['$ '?e]}
|
|
||||||
history id)
|
|
||||||
[last-transaction] (->> txs (sort-by first) (last))
|
|
||||||
tx [[:upsert-invoice
|
|
||||||
(->> txs
|
|
||||||
(filter (fn [[tx]] (= tx last-transaction)))
|
|
||||||
(reduce (fn [new-transaction [_ entity original-status original-outstanding total expense-account expense-account-amount]]
|
|
||||||
(-> new-transaction
|
|
||||||
(assoc :db/id entity
|
|
||||||
:invoice/total total
|
|
||||||
:invoice/status original-status
|
|
||||||
:invoice/outstanding-balance original-outstanding)
|
|
||||||
(update :invoice/expense-accounts (fnil conj []) {:db/id expense-account :invoice-expense-account/amount expense-account-amount})))
|
|
||||||
{}))]]
|
|
||||||
_ (audit-transact tx identity)]
|
|
||||||
(alog/info ::unvoiding-invoice :transaction :tx)
|
|
||||||
(html-response
|
|
||||||
(row* identity (dc/pull (dc/db conn) default-read id) {:flash? true
|
|
||||||
:request request})
|
|
||||||
:headers (cond-> {"hx-retarget" (format "#entity-table tr[data-id=\"%d\"]" id)
|
|
||||||
"hx-reswap" "outerHTML"}))))
|
|
||||||
|
|
||||||
(defn delete [{invoice :entity :as request identity :identity}]
|
(defn delete [{invoice :entity :as request identity :identity}]
|
||||||
(exception->notification
|
(exception->notification
|
||||||
#(when-not (= :invoice-status/unpaid (:invoice/status invoice))
|
#(when-not (= :invoice-status/unpaid (:invoice/status invoice))
|
||||||
@@ -653,18 +643,6 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
(defn bulk-delete-dialog-confirm [request]
|
|
||||||
(alog/peek (:form-params request))
|
|
||||||
(let [ids (selected->ids request (:form-params request))
|
|
||||||
updated-count (void-invoices-internal ids (:identity request))]
|
|
||||||
|
|
||||||
(html-response [:div]
|
|
||||||
:headers {"hx-trigger" (hx/json {:modalclose ""
|
|
||||||
:notification (format "Successfully voided %d of %d invoices."
|
|
||||||
updated-count
|
|
||||||
(count ids))})})))
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -678,30 +656,29 @@
|
|||||||
(not bank-account-belongs?)
|
(not bank-account-belongs?)
|
||||||
(update :query-params dissoc :bank-account))))))
|
(update :query-params dissoc :bank-account))))))
|
||||||
|
|
||||||
(defn wrap-status-from-source [handler]
|
(defn wrap-external-from-route [handler]
|
||||||
(fn [{:keys [matched-current-page-route] :as request}]
|
(fn [{:keys [matched-current-page-route] :as request}]
|
||||||
(let [request (cond-> request
|
(let [request (cond-> request
|
||||||
(= ::route/paid-page matched-current-page-route) (assoc-in [:route-params :status] :invoice-status/paid)
|
(= ::route/external-page matched-current-page-route) (assoc-in [:route-params :external?] true))]
|
||||||
(= ::route/unpaid-page matched-current-page-route) (assoc-in [:route-params :status] :invoice-status/unpaid)
|
|
||||||
(= ::route/voided-page matched-current-page-route) (assoc-in [:route-params :status] :invoice-status/voided)
|
|
||||||
(= ::route/all-page matched-current-page-route) (assoc-in [:route-params :status] nil))]
|
|
||||||
(handler request))))
|
(handler request))))
|
||||||
|
|
||||||
|
|
||||||
(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 :parse-query-params? false)
|
||||||
(wrap-implied-route-param :status nil))
|
(wrap-implied-route-param :external? false))
|
||||||
|
::route/external-page (-> (helper/page-route grid-page :parse-query-params? false)
|
||||||
|
(wrap-implied-route-param :external? true))
|
||||||
|
|
||||||
::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})
|
::route/bank-account-filter bank-account-filter})
|
||||||
(fn [h]
|
(fn [h]
|
||||||
(-> h
|
(-> h
|
||||||
(wrap-copy-qp-pqp)
|
(wrap-copy-qp-pqp)
|
||||||
(wrap-status-from-source)
|
|
||||||
(wrap-apply-sort grid-page)
|
(wrap-apply-sort grid-page)
|
||||||
(wrap-ensure-bank-account-belongs)
|
(wrap-ensure-bank-account-belongs)
|
||||||
(wrap-merge-prior-hx)
|
(wrap-merge-prior-hx)
|
||||||
|
(wrap-external-from-route)
|
||||||
(wrap-schema-enforce :query-schema query-schema)
|
(wrap-schema-enforce :query-schema query-schema)
|
||||||
(wrap-schema-enforce :hx-schema query-schema)
|
(wrap-schema-enforce :hx-schema query-schema)
|
||||||
(wrap-client-redirect-unauthenticated)))))
|
(wrap-client-redirect-unauthenticated)))))
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
(ns auto-ap.routes.ledger)
|
(ns auto-ap.routes.ledger)
|
||||||
|
|
||||||
(def routes {"" {:get ::all-page}
|
(def routes {"" {:get ::all-page}
|
||||||
|
"/external-new" ::external-page
|
||||||
"/table" ::table
|
"/table" ::table
|
||||||
"/bank-account-filter" ::bank-account-filter})
|
"/bank-account-filter" ::bank-account-filter})
|
||||||
Reference in New Issue
Block a user