Compare commits
5 Commits
de1c154706
...
feat/compl
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b02aec3546 | ||
|
|
5a39a0c762 | ||
| 95f12a6072 | |||
| 0e76506c22 | |||
| baf8cfff97 |
File diff suppressed because one or more lines are too long
@@ -178,8 +178,7 @@
|
|||||||
(conj
|
(conj
|
||||||
(table->pdf report
|
(table->pdf report
|
||||||
(cond-> (into [30 ] (repeat client-count 13))
|
(cond-> (into [30 ] (repeat client-count 13))
|
||||||
(:include-comparison args) (into (repeat (* 2 client-count) 13))
|
(:include-comparison args) (into (repeat (* 2 client-count) 13))))))
|
||||||
(and (> client-count 1) (not (:include-comparison args))) (conj 13)))))
|
|
||||||
output-stream)
|
output-stream)
|
||||||
(.toByteArray output-stream)))
|
(.toByteArray output-stream)))
|
||||||
|
|
||||||
|
|||||||
@@ -120,8 +120,7 @@
|
|||||||
(list
|
(list
|
||||||
[:div.text-2xl.font-bold.text-gray-600 (str "Balance Sheet - " (str/join ", " (map :client/name client))) ]
|
[:div.text-2xl.font-bold.text-gray-600 (str "Balance Sheet - " (str/join ", " (map :client/name client))) ]
|
||||||
(rtable/table {:widths (cond-> (into [30 ] (repeat 13 client-count))
|
(rtable/table {:widths (cond-> (into [30 ] (repeat 13 client-count))
|
||||||
(> (count date) 1) (into (repeat 13 (* 2 client-count (dec (count date)))))
|
(> (count date) 1) (into (repeat 13 (* 2 client-count (dec (count date))))))
|
||||||
(and (> client-count 1) (= (count date) 1)) (conj 13))
|
|
||||||
:investigate-url (bidi.bidi/path-for ssr-routes/only-routes ::route/investigate)
|
:investigate-url (bidi.bidi/path-for ssr-routes/only-routes ::route/investigate)
|
||||||
:table report
|
:table report
|
||||||
:warning (not-empty (str/join "\n " (filter not-empty [warning (:warning report)])))} ))))])
|
:warning (not-empty (str/join "\n " (filter not-empty [warning (:warning report)])))} ))))])
|
||||||
@@ -203,8 +202,7 @@
|
|||||||
(conj
|
(conj
|
||||||
(table->pdf report
|
(table->pdf report
|
||||||
(cond-> (into [30 ] (repeat client-count 13))
|
(cond-> (into [30 ] (repeat client-count 13))
|
||||||
(> (count date) 1) (into (repeat (* 2 client-count (dec (count date))) 13 ))
|
(> (count date) 1) (into (repeat (* 2 client-count (dec (count date))) 13 ))))))
|
||||||
(and (> client-count 1) (= (count date) 1)) (conj 13)))))
|
|
||||||
output-stream)
|
output-stream)
|
||||||
(.toByteArray output-stream)))
|
(.toByteArray output-stream)))
|
||||||
|
|
||||||
|
|||||||
@@ -6,12 +6,10 @@
|
|||||||
[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.query-params :refer [wrap-copy-qp-pqp]]
|
[auto-ap.query-params :refer [wrap-copy-qp-pqp]]
|
||||||
[auto-ap.client-routes :as client-routes]
|
|
||||||
[auto-ap.routes.pos.sales-summaries :as route]
|
[auto-ap.routes.pos.sales-summaries :as route]
|
||||||
[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.link-dropdown :refer [link-dropdown]]
|
|
||||||
[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 :refer [wrap-apply-sort]]
|
[auto-ap.ssr.grid-page-helper :as helper :refer [wrap-apply-sort]]
|
||||||
@@ -29,7 +27,7 @@
|
|||||||
[clojure.string :as str]
|
[clojure.string :as str]
|
||||||
[datomic.api :as dc]
|
[datomic.api :as dc]
|
||||||
[hiccup.util :as hu]
|
[hiccup.util :as hu]
|
||||||
[iol-ion.query :refer [dollars= dollars-0?]]
|
[iol-ion.query :refer [dollars=]]
|
||||||
[malli.core :as mc]
|
[malli.core :as mc]
|
||||||
[malli.util :as mut]))
|
[malli.util :as mut]))
|
||||||
|
|
||||||
@@ -40,7 +38,7 @@
|
|||||||
[:start-date {:optional true}
|
[:start-date {:optional true}
|
||||||
[:maybe clj-date-schema]]
|
[:maybe clj-date-schema]]
|
||||||
[:end-date {:optional true}
|
[:end-date {:optional true}
|
||||||
[:maybe clj-date-schema]]]
|
[:maybe clj-date-schema]] ]
|
||||||
default-grid-fields-schema)]))
|
default-grid-fields-schema)]))
|
||||||
|
|
||||||
(defn filters [request]
|
(defn filters [request]
|
||||||
@@ -57,14 +55,15 @@
|
|||||||
*
|
*
|
||||||
[:sales-summary/date :xform clj-time.coerce/from-date]
|
[:sales-summary/date :xform clj-time.coerce/from-date]
|
||||||
{:sales-summary/client [:client/code :client/name :db/id]}
|
{:sales-summary/client [:client/code :client/name :db/id]}
|
||||||
{:sales-summary/items [{[:ledger-mapped/ledger-side :xform iol-ion.query/ident] [:db/ident]}
|
{:sales-summary/items [{[:ledger-mapped/ledger-side :xform iol-ion.query/ident] [:db/ident]
|
||||||
|
}
|
||||||
:ledger-mapped/account
|
:ledger-mapped/account
|
||||||
:ledger-mapped/amount
|
:ledger-mapped/amount
|
||||||
:sales-summary-item/category
|
:sales-summary-item/category
|
||||||
:sales-summary-item/sort-order
|
:sales-summary-item/sort-order
|
||||||
:db/id
|
:db/id
|
||||||
:sales-summary-item/manual?]}
|
:sales-summary-item/manual?]
|
||||||
{:journal-entry/original-entity [:db/id]}])
|
} ])
|
||||||
|
|
||||||
(defn fetch-ids [db request]
|
(defn fetch-ids [db request]
|
||||||
(let [query-params (:query-params request)
|
(let [query-params (:query-params request)
|
||||||
@@ -91,6 +90,7 @@
|
|||||||
:where [[(< ?d ?end-date)]]}
|
:where [[(< ?d ?end-date)]]}
|
||||||
:args [(-> query-params :end-date c/to-date)]})
|
:args [(-> query-params :end-date c/to-date)]})
|
||||||
|
|
||||||
|
|
||||||
true
|
true
|
||||||
(merge-query {:query {:find ['?sort-default '?e]
|
(merge-query {:query {:find ['?sort-default '?e]
|
||||||
:where ['[?e :sales-summary/date ?sort-default]]}}))]
|
:where ['[?e :sales-summary/date ?sort-default]]}}))]
|
||||||
@@ -116,6 +116,9 @@
|
|||||||
(defn sort-items [ss]
|
(defn sort-items [ss]
|
||||||
(sort-by (juxt :ledger-mapped/ledger-side :sales-summary-item/sort-order :sales-summary-item/category) ss))
|
(sort-by (juxt :ledger-mapped/ledger-side :sales-summary-item/sort-order :sales-summary-item/category) ss))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
(defn total-debits [items]
|
(defn total-debits [items]
|
||||||
(->> items
|
(->> items
|
||||||
(filter #(= :ledger-side/debit (:ledger-mapped/ledger-side %)))
|
(filter #(= :ledger-side/debit (:ledger-mapped/ledger-side %)))
|
||||||
@@ -128,11 +131,6 @@
|
|||||||
(map #(:ledger-mapped/amount % 0.0))
|
(map #(:ledger-mapped/amount % 0.0))
|
||||||
(reduce + 0.0)))
|
(reduce + 0.0)))
|
||||||
|
|
||||||
(defn truncate [s max-len]
|
|
||||||
(if (> (count s) max-len)
|
|
||||||
(str (subs s 0 (- max-len 3)) "...")
|
|
||||||
s))
|
|
||||||
|
|
||||||
(def grid-page
|
(def grid-page
|
||||||
(helper/build {:id "entity-table"
|
(helper/build {:id "entity-table"
|
||||||
:id-fn :db/id
|
:id-fn :db/id
|
||||||
@@ -165,100 +163,46 @@
|
|||||||
(= (count (:clients args)) 1))
|
(= (count (:clients args)) 1))
|
||||||
:render #(-> % :sales-summary/client :client/code)}
|
:render #(-> % :sales-summary/client :client/code)}
|
||||||
|
|
||||||
|
|
||||||
{:key "date"
|
{:key "date"
|
||||||
:name "Date"
|
:name "Date"
|
||||||
:sort-key "date"
|
:sort-key "date"
|
||||||
:render #(some-> % :sales-summary/date (atime/unparse-local atime/normal-date))}
|
:render #(some-> % :sales-summary/date (atime/unparse-local atime/normal-date))}
|
||||||
|
|
||||||
|
|
||||||
{:key "debits"
|
{:key "debits"
|
||||||
:name "Debits"
|
:name "debits"
|
||||||
:sort-key "debits"
|
:sort-key "debits"
|
||||||
:class "w-72 align-top"
|
|
||||||
:render (fn [ss]
|
:render (fn [ss]
|
||||||
(let [items (:sales-summary/items ss)
|
(let [total-debits (total-debits (:sales-summary/items ss))
|
||||||
debit-items (filter #(= :ledger-side/debit (:ledger-mapped/ledger-side %)) (sort-items items))
|
total-credits (total-credits (:sales-summary/items ss))]
|
||||||
credit-count (count (filter #(= :ledger-side/credit (:ledger-mapped/ledger-side %)) items))
|
[:ul
|
||||||
total-debits (total-debits items)]
|
(for [si (sort-items (:sales-summary/items ss))
|
||||||
[:div.flex.flex-col.h-full
|
:when (= :ledger-side/debit (:ledger-mapped/ledger-side si))]
|
||||||
[:ul.flex-grow
|
[:li (:sales-summary-item/category si) ": " (format "$%,.2f" (:ledger-mapped/amount si))
|
||||||
(for [si debit-items]
|
|
||||||
[:li.flex.items-baseline.gap-2.py-0.5.text-sm.text-gray-700
|
|
||||||
[:span.flex-1.min-w-0.truncate.text-gray-600
|
|
||||||
(:sales-summary-item/category si)]
|
|
||||||
(when-not (:ledger-mapped/account si)
|
(when-not (:ledger-mapped/account si)
|
||||||
[:span.shrink-0 (com/pill {:color :red} "?")])
|
[:span.pl-4 (com/pill {:color :red}
|
||||||
[:span.shrink-0.font-mono.tabular-nums.text-right.text-gray-900.whitespace-nowrap
|
"missing account")])]
|
||||||
(format "$%,.2f" (:ledger-mapped/amount si))]])
|
)
|
||||||
(for [_ (range (max 0 (- credit-count (count debit-items))))]
|
[:li (com/pill {:color (if (dollars= total-debits total-credits)
|
||||||
[:li.py-0.5.text-sm " "])]
|
:primary
|
||||||
[:div.border-t-2.border-gray-300.mt-1.pt-1.flex.justify-between.items-baseline
|
:red)} "Total: " (format "$%,.2f" total-debits))]]))}
|
||||||
[:span.text-xs.uppercase.tracking-wider.font-semibold.text-gray-500 "Total"]
|
|
||||||
[:span.font-mono.tabular-nums.font-bold.text-gray-900
|
|
||||||
(format "$%,.2f" total-debits)]]]))}
|
|
||||||
|
|
||||||
{:key "credits"
|
{:key "credits"
|
||||||
:name "Credits"
|
:name "credits"
|
||||||
:sort-key "credits"
|
:sort-key "credits"
|
||||||
:class "w-72 align-top"
|
|
||||||
:render (fn [ss]
|
:render (fn [ss]
|
||||||
(let [items (:sales-summary/items ss)
|
(let [total-debits (total-debits (:sales-summary/items ss))
|
||||||
credit-items (filter #(= :ledger-side/credit (:ledger-mapped/ledger-side %)) (sort-items items))
|
total-credits (total-credits (:sales-summary/items ss))]
|
||||||
debit-count (count (filter #(= :ledger-side/debit (:ledger-mapped/ledger-side %)) items))
|
[:ul
|
||||||
total-credits (total-credits items)]
|
(for [si (sort-items (:sales-summary/items ss))
|
||||||
[:div.flex.flex-col.h-full
|
:when (= :ledger-side/credit (:ledger-mapped/ledger-side si))]
|
||||||
[:ul.flex-grow
|
[:li (:sales-summary-item/category si) ": " (format "$%,.2f" (:ledger-mapped/amount si))
|
||||||
(for [si credit-items]
|
|
||||||
[:li.flex.items-baseline.gap-2.py-0.5.text-sm.text-gray-700
|
|
||||||
[:span.flex-1.min-w-0.truncate.text-gray-600
|
|
||||||
(:sales-summary-item/category si)]
|
|
||||||
(when-not (:ledger-mapped/account si)
|
(when-not (:ledger-mapped/account si)
|
||||||
[:span.shrink-0 (com/pill {:color :red} "?")])
|
[:span.pl-4 (com/pill {:color :red}
|
||||||
[:span.shrink-0.font-mono.tabular-nums.text-right.text-gray-900.whitespace-nowrap
|
"missing account")])])
|
||||||
(format "$%,.2f" (:ledger-mapped/amount si))]])
|
[:li (com/pill {:color (if (dollars= total-debits total-credits)
|
||||||
(for [_ (range (max 0 (- debit-count (count credit-items))))]
|
:primary
|
||||||
[:li.py-0.5.text-sm " "])]
|
:red)} "Total: " (format "$%,.2f" total-credits))]]))}]}))
|
||||||
[:div.border-t-2.border-gray-300.mt-1.pt-1.flex.justify-between.items-baseline
|
|
||||||
[:span.text-xs.uppercase.tracking-wider.font-semibold.text-gray-500 "Total"]
|
|
||||||
[:span.font-mono.tabular-nums.font-bold.text-gray-900
|
|
||||||
(format "$%,.2f" total-credits)]]]))}
|
|
||||||
|
|
||||||
{:key "balance"
|
|
||||||
:name "Status"
|
|
||||||
:sort-key "balance"
|
|
||||||
:class "w-28 align-top"
|
|
||||||
:render (fn [ss]
|
|
||||||
(let [items (:sales-summary/items ss)
|
|
||||||
total-debits (total-debits items)
|
|
||||||
total-credits (total-credits items)
|
|
||||||
delta (- total-debits total-credits)
|
|
||||||
balanced? (dollars= total-debits total-credits)
|
|
||||||
missing-account? (some #(not (:ledger-mapped/account %)) items)]
|
|
||||||
[:div.flex.flex-col.items-center.gap-1.pt-2
|
|
||||||
(when missing-account?
|
|
||||||
[:span.inline-block.text-xs.font-semibold.uppercase.tracking-wider.text-amber-800.bg-amber-100.border.border-amber-300.rounded-sm.px-1.5.py-0.5
|
|
||||||
"Missing acct"])
|
|
||||||
(if balanced?
|
|
||||||
(when-not missing-account?
|
|
||||||
[:span.inline-block.text-xs.font-semibold.uppercase.tracking-wider.text-emerald-800.bg-emerald-100.border.border-emerald-300.rounded-sm.px-1.5.py-0.5
|
|
||||||
"Balanced"])
|
|
||||||
[:div.flex.flex-col.items-center
|
|
||||||
[:span.font-mono.tabular-nums.text-red-700.font-bold.text-sm
|
|
||||||
(format "$%,.2f" (Math/abs delta))]
|
|
||||||
[:span.text-xs.uppercase.tracking-wider.text-red-600.font-medium.mt-0.5
|
|
||||||
(if (> total-debits total-credits) "Debit over" "Credit over")]])]))}
|
|
||||||
|
|
||||||
{:key "links"
|
|
||||||
:name "Links"
|
|
||||||
:show-starting "lg"
|
|
||||||
:class "w-8"
|
|
||||||
:render (fn [ss]
|
|
||||||
(let [ledger-entry (:journal-entry/original-entity ss)]
|
|
||||||
(when (seq ledger-entry)
|
|
||||||
(link-dropdown
|
|
||||||
[{:link (hu/url (bidi/path-for client-routes/routes :ledger)
|
|
||||||
{:exact-match-id (:db/id (first ledger-entry))})
|
|
||||||
:color :yellow
|
|
||||||
:content "Ledger entry"}]))))}]}))
|
|
||||||
|
|
||||||
(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))
|
||||||
@@ -289,7 +233,8 @@
|
|||||||
:error/path [:credit]}
|
:error/path [:credit]}
|
||||||
(fn [x]
|
(fn [x]
|
||||||
(not (and (:credit x)
|
(not (and (:credit x)
|
||||||
(:debit x))))]]]]])
|
(:debit x))))]]]] ])
|
||||||
|
|
||||||
|
|
||||||
(defn summary-total-row* [request]
|
(defn summary-total-row* [request]
|
||||||
(let [total-credits (-> request
|
(let [total-credits (-> request
|
||||||
@@ -304,22 +249,16 @@
|
|||||||
(total-debits))]
|
(total-debits))]
|
||||||
|
|
||||||
(com/data-grid-row {:id "total-row"
|
(com/data-grid-row {:id "total-row"
|
||||||
:class "bg-slate-50 border-t-2 border-slate-300"
|
|
||||||
:hx-trigger "change from:closest form target:.amount-field"
|
:hx-trigger "change from:closest form target:.amount-field"
|
||||||
:hx-put (bidi.bidi/path-for ssr-routes/only-routes ::route/expense-account-total)
|
:hx-put (bidi.bidi/path-for ssr-routes/only-routes ::route/expense-account-total)
|
||||||
:hx-target "this"
|
:hx-target "this"
|
||||||
:hx-swap "innerHTML"}
|
:hx-swap "innerHTML"}
|
||||||
(com/data-grid-cell {})
|
(com/data-grid-cell {})
|
||||||
|
(com/data-grid-cell {:class "text-right"} [:span.font-bold.text-right "TOTAL"])
|
||||||
(com/data-grid-cell {:class "text-right"}
|
(com/data-grid-cell {:class "text-right"}
|
||||||
[:span.text-xs.uppercase.tracking-wider.font-semibold.text-slate-600
|
(format "$%,.2f" total-debits))
|
||||||
"Total"])
|
|
||||||
(com/data-grid-cell {:class "text-right"}
|
(com/data-grid-cell {:class "text-right"}
|
||||||
[:span.font-mono.tabular-nums.font-bold.text-slate-900
|
(format "$%,.2f" total-credits)))))
|
||||||
(format "$%,.2f" total-debits)])
|
|
||||||
(com/data-grid-cell {:class "text-right"}
|
|
||||||
[:span.font-mono.tabular-nums.font-bold.text-slate-900
|
|
||||||
(format "$%,.2f" total-credits)])
|
|
||||||
(com/data-grid-cell {}))))
|
|
||||||
|
|
||||||
(defn unbalanced-row* [request]
|
(defn unbalanced-row* [request]
|
||||||
(let [total-credits (-> request
|
(let [total-credits (-> request
|
||||||
@@ -331,31 +270,25 @@
|
|||||||
:multi-form-state
|
:multi-form-state
|
||||||
:step-params
|
:step-params
|
||||||
:sales-summary/items
|
:sales-summary/items
|
||||||
(total-debits))
|
(total-debits))]
|
||||||
unbalanced? (not (dollars= total-credits total-debits))
|
|
||||||
debit-over? (and unbalanced? (> total-debits total-credits))
|
|
||||||
credit-over? (and unbalanced? (> total-credits total-debits))]
|
|
||||||
|
|
||||||
(com/data-grid-row {:id "unbalanced-row"
|
(com/data-grid-row {:id "total-row"
|
||||||
:class (when unbalanced? "bg-red-50 border-t border-red-200")
|
|
||||||
:hx-trigger "change from:closest form target:.amount-field"
|
:hx-trigger "change from:closest form target:.amount-field"
|
||||||
:hx-put (bidi.bidi/path-for ssr-routes/only-routes ::route/expense-account-total)
|
:hx-put (bidi.bidi/path-for ssr-routes/only-routes ::route/expense-account-total)
|
||||||
:hx-target "this"
|
:hx-target "this"
|
||||||
:hx-swap "innerHTML"}
|
:hx-swap "innerHTML"}
|
||||||
(com/data-grid-cell {})
|
(com/data-grid-cell {})
|
||||||
|
(com/data-grid-cell {:class "text-right"} [:span.font-bold.text-right "UNBALANCED"])
|
||||||
(com/data-grid-cell {:class "text-right"}
|
(com/data-grid-cell {:class "text-right"}
|
||||||
(when unbalanced?
|
(when (and
|
||||||
[:span.text-xs.uppercase.tracking-wider.font-semibold.text-red-700
|
(not (dollars= total-credits total-debits))
|
||||||
"Out of balance"]))
|
(> total-debits total-credits))
|
||||||
|
(format "$%,.2f" (- total-debits total-credits))))
|
||||||
(com/data-grid-cell {:class "text-right"}
|
(com/data-grid-cell {:class "text-right"}
|
||||||
(when debit-over?
|
(when
|
||||||
[:span.font-mono.tabular-nums.font-bold.text-red-700
|
(and (not (dollars= total-credits total-debits))
|
||||||
(format "$%,.2f" (- total-debits total-credits))]))
|
(> total-credits total-debits))
|
||||||
(com/data-grid-cell {:class "text-right"}
|
(format "$%,.2f" (- total-credits total-debits)))))))
|
||||||
(when credit-over?
|
|
||||||
[:span.font-mono.tabular-nums.font-bold.text-red-700
|
|
||||||
(format "$%,.2f" (- total-credits total-debits))]))
|
|
||||||
(com/data-grid-cell {}))))
|
|
||||||
|
|
||||||
(defn- account-typeahead*
|
(defn- account-typeahead*
|
||||||
[{:keys [name value client-id]}]
|
[{:keys [name value client-id]}]
|
||||||
@@ -373,10 +306,8 @@
|
|||||||
(defn sales-summary-item-row* [{:keys [value client-id]}]
|
(defn sales-summary-item-row* [{:keys [value client-id]}]
|
||||||
(let [manual? (fc/field-value (:sales-summary-item/manual? value))]
|
(let [manual? (fc/field-value (:sales-summary-item/manual? value))]
|
||||||
(com/data-grid-row (cond-> {:x-ref "p"
|
(com/data-grid-row (cond-> {:x-ref "p"
|
||||||
:x-data (hx/json {})
|
:x-data (hx/json {})}
|
||||||
:class (when manual?
|
(fc/field-value (:new? value)) (hx/htmx-transition-appear ))
|
||||||
"bg-indigo-50/40 border-l-2 border-indigo-300")}
|
|
||||||
(fc/field-value (:new? value)) (hx/htmx-transition-appear))
|
|
||||||
(fc/with-field :db/id
|
(fc/with-field :db/id
|
||||||
(com/hidden {:name (fc/field-name)
|
(com/hidden {:name (fc/field-name)
|
||||||
:value (fc/field-value)}))
|
:value (fc/field-value)}))
|
||||||
@@ -384,7 +315,7 @@
|
|||||||
(fc/with-field :sales-summary-item/manual?
|
(fc/with-field :sales-summary-item/manual?
|
||||||
(com/hidden {:name (fc/field-name)
|
(com/hidden {:name (fc/field-name)
|
||||||
:value true})))
|
:value true})))
|
||||||
(com/data-grid-cell {:class "align-top"}
|
(com/data-grid-cell {}
|
||||||
(fc/with-field :sales-summary-item/category
|
(fc/with-field :sales-summary-item/category
|
||||||
(if manual?
|
(if manual?
|
||||||
(com/validated-field {:errors (fc/field-errors)}
|
(com/validated-field {:errors (fc/field-errors)}
|
||||||
@@ -395,38 +326,35 @@
|
|||||||
(list
|
(list
|
||||||
(com/hidden {:name (fc/field-name)
|
(com/hidden {:name (fc/field-name)
|
||||||
:value (fc/field-value)})
|
:value (fc/field-value)})
|
||||||
[:span.text-sm.text-gray-700
|
(fc/field-value (:sales-summary-item/category value))))))
|
||||||
(fc/field-value (:sales-summary-item/category value))]))))
|
(com/data-grid-cell {}
|
||||||
(com/data-grid-cell {:class "align-top"}
|
|
||||||
(fc/with-field :ledger-mapped/account
|
(fc/with-field :ledger-mapped/account
|
||||||
(com/validated-field {:errors (fc/field-errors)}
|
(com/validated-field {:errors (fc/field-errors)}
|
||||||
(account-typeahead* {:value (fc/field-value)
|
(account-typeahead* {:value (fc/field-value)
|
||||||
:client-id client-id
|
:client-id client-id
|
||||||
:name (fc/field-name)}))))
|
:name (fc/field-name)}))))
|
||||||
(com/data-grid-cell {:class "text-right align-top"}
|
(com/data-grid-cell {:class "text-right"}
|
||||||
|
|
||||||
(if manual?
|
(if manual?
|
||||||
(fc/with-field :debit
|
(fc/with-field :debit
|
||||||
(com/validated-field {:errors (fc/field-errors)}
|
(com/validated-field {:errors (fc/field-errors)}
|
||||||
(com/money-input {:class "w-24 text-right font-mono tabular-nums"
|
(com/money-input {:class "w-24"
|
||||||
:name (fc/field-name)
|
:name (fc/field-name)
|
||||||
:value (fc/field-value)})))
|
:value (fc/field-value)})))
|
||||||
(when (= (fc/field-value (:ledger-mapped/ledger-side value))
|
(when (= (fc/field-value (:ledger-mapped/ledger-side value))
|
||||||
:ledger-side/debit)
|
:ledger-side/debit)
|
||||||
[:span.font-mono.tabular-nums.text-gray-900.text-sm.whitespace-nowrap
|
(format "$%,.2f" (fc/field-value (:ledger-mapped/amount value))))))
|
||||||
(format "$%,.2f" (fc/field-value (:ledger-mapped/amount value)))])))
|
(com/data-grid-cell {:class "text-right"}
|
||||||
(com/data-grid-cell {:class "text-right align-top"}
|
|
||||||
|
|
||||||
(if manual?
|
(if manual?
|
||||||
(fc/with-field :credit
|
(fc/with-field :credit
|
||||||
(com/validated-field {:errors (fc/field-errors)}
|
(com/validated-field {:errors (fc/field-errors)}
|
||||||
(com/money-input {:class "w-24 text-right font-mono tabular-nums"
|
(com/money-input {:class "w-24"
|
||||||
:name (fc/field-name)
|
:name (fc/field-name)
|
||||||
:value (fc/field-value)})))
|
:value (fc/field-value)})))
|
||||||
(when (= (fc/field-value (:ledger-mapped/ledger-side value))
|
(when (= (fc/field-value (:ledger-mapped/ledger-side value))
|
||||||
:ledger-side/credit)
|
:ledger-side/credit)
|
||||||
[:span.font-mono.tabular-nums.text-gray-900.text-sm.whitespace-nowrap
|
(format "$%,.2f" (fc/field-value (:ledger-mapped/amount value))))))
|
||||||
(format "$%,.2f" (fc/field-value (:ledger-mapped/amount value)))])))
|
|
||||||
(com/data-grid-cell {:class "align-top"}
|
(com/data-grid-cell {:class "align-top"}
|
||||||
(when manual?
|
(when manual?
|
||||||
(com/a-icon-button {"@click.prevent.stop" "$refs.p.remove()"} svg/x))))))
|
(com/a-icon-button {"@click.prevent.stop" "$refs.p.remove()"} svg/x))))))
|
||||||
@@ -464,7 +392,7 @@
|
|||||||
(fc/with-field :sales-summary/items
|
(fc/with-field :sales-summary/items
|
||||||
(list
|
(list
|
||||||
(fc/cursor-map #(sales-summary-item-row* {:value %
|
(fc/cursor-map #(sales-summary-item-row* {:value %
|
||||||
:client-id (:db/id (:sales-summary/client (:snapshot multi-form-state)))}))
|
:client-id (:db/id (:sales-summary/client (:snapshot multi-form-state))) }))
|
||||||
(com/data-grid-new-row {:colspan 5
|
(com/data-grid-new-row {:colspan 5
|
||||||
:hx-get (bidi/path-for ssr-routes/only-routes ::route/new-summary-item)
|
:hx-get (bidi/path-for ssr-routes/only-routes ::route/new-summary-item)
|
||||||
:row-offset 0
|
:row-offset 0
|
||||||
@@ -472,12 +400,12 @@
|
|||||||
:tr-params {:hx-vals (hx/json {:client-id (:db/id (:sales-summary/client (:snapshot multi-form-state)))})}}
|
:tr-params {:hx-vals (hx/json {:client-id (:db/id (:sales-summary/client (:snapshot multi-form-state)))})}}
|
||||||
"New Summary Item")))
|
"New Summary Item")))
|
||||||
(summary-total-row* request)
|
(summary-total-row* request)
|
||||||
(unbalanced-row* request))])
|
(unbalanced-row* request)) ])
|
||||||
|
|
||||||
:footer
|
:footer
|
||||||
(mm/default-step-footer linear-wizard this :validation-route ::route/edit-wizard-navigate)
|
(mm/default-step-footer linear-wizard this :validation-route ::route/edit-wizard-navigate)
|
||||||
:validation-route ::route/edit-wizard-navigate
|
:validation-route ::route/edit-wizard-navigate
|
||||||
:width-height-class "lg:w-[920px] lg:h-[640px]")))
|
:width-height-class "lg:w-[850px] lg:h-[900px]")))
|
||||||
|
|
||||||
(defn attach-ledger [i]
|
(defn attach-ledger [i]
|
||||||
(cond-> i
|
(cond-> i
|
||||||
@@ -515,17 +443,18 @@
|
|||||||
(form-schema [_]
|
(form-schema [_]
|
||||||
edit-schema)
|
edit-schema)
|
||||||
(submit [this {:keys [multi-form-state request-method identity] :as request}]
|
(submit [this {:keys [multi-form-state request-method identity] :as request}]
|
||||||
(let [result (:snapshot multi-form-state)
|
(let [result (:snapshot multi-form-state )
|
||||||
transaction [:upsert-sales-summary {:db/id (:db/id result)
|
transaction [:upsert-sales-summary {:db/id (:db/id result)
|
||||||
:sales-summary/items (map
|
:sales-summary/items (map
|
||||||
(fn [i]
|
(fn [i]
|
||||||
(if (:sales-summary-item/manual? i)
|
(if (:sales-summary-item/manual? i)
|
||||||
(attach-ledger i)
|
(attach-ledger i)
|
||||||
{:db/id (:db/id i)
|
{:db/id (:db/id i)
|
||||||
:ledger-mapped/account (:ledger-mapped/account i)}))
|
:ledger-mapped/account (:ledger-mapped/account i)
|
||||||
|
}))
|
||||||
(:sales-summary/items result))}]]
|
(:sales-summary/items result))}]]
|
||||||
(clojure.pprint/pprint (:sales-summary/items result))
|
(clojure.pprint/pprint (:sales-summary/items result))
|
||||||
@(dc/transact conn [transaction])
|
@(dc/transact conn [ transaction])
|
||||||
(html-response
|
(html-response
|
||||||
(row* identity (dc/pull (dc/db conn) default-read (:db/id result))
|
(row* identity (dc/pull (dc/db conn) default-read (:db/id result))
|
||||||
{:flash? true
|
{:flash? true
|
||||||
|
|||||||
@@ -798,23 +798,20 @@
|
|||||||
|
|
||||||
|
|
||||||
(defn balance-sheet-headers [pnl-data]
|
(defn balance-sheet-headers [pnl-data]
|
||||||
(let [period-count (count (:periods (:args pnl-data)))
|
(let [period-count (count (:periods (:args pnl-data)))]
|
||||||
client-ids (set (map :client-id (:data pnl-data)))
|
|
||||||
client-count (count client-ids)
|
|
||||||
show-total? (and (> client-count 1) (= 1 period-count))]
|
|
||||||
(cond-> []
|
(cond-> []
|
||||||
(> client-count 1)
|
(> (count (set (map :client-id (:data pnl-data)))) 1)
|
||||||
(conj (cond-> (into [{:value "Client"}]
|
(conj (into [{:value "Client"}]
|
||||||
(mapcat identity
|
|
||||||
(for [client client-ids]
|
|
||||||
(cond-> [{:value (str (-> pnl-data :client-codes (get client)))}]
|
|
||||||
(> period-count 1)
|
|
||||||
(into (apply concat (repeat (dec period-count) ["" ""])))))))
|
|
||||||
show-total? (conj {:value "Total" :bold true :border [:left]})))
|
|
||||||
|
|
||||||
|
(mapcat identity
|
||||||
|
(for [client (set (map :client-id (:data pnl-data))) ]
|
||||||
|
(cond-> [{:value (str (-> pnl-data :client-codes (get client)))}]
|
||||||
|
|
||||||
|
(> period-count 1)
|
||||||
|
(into (apply concat (repeat (dec period-count) ["" ""]))))))))
|
||||||
true
|
true
|
||||||
(conj (cond-> (into [{:value "Period Ending"}]
|
(conj (into [{:value "Period Ending"}]
|
||||||
(for [client client-ids
|
(for [client (set (map :client-id (:data pnl-data)))
|
||||||
[index p] (map vector (range) (:periods (:args pnl-data)))
|
[index p] (map vector (range) (:periods (:args pnl-data)))
|
||||||
:let [is-first? (= 0 index)
|
:let [is-first? (= 0 index)
|
||||||
period-date (date->str p)
|
period-date (date->str p)
|
||||||
@@ -824,8 +821,7 @@
|
|||||||
[{:value period-date}
|
[{:value period-date}
|
||||||
{:value "+/-"}])]
|
{:value "+/-"}])]
|
||||||
header period-headers]
|
header period-headers]
|
||||||
header))
|
header))))))
|
||||||
show-total? (conj {:value (date->str (first (:periods (:args pnl-data)))) :border [:left]}))))))
|
|
||||||
|
|
||||||
(defn append-deltas [table]
|
(defn append-deltas [table]
|
||||||
(->> table
|
(->> table
|
||||||
@@ -894,33 +890,12 @@
|
|||||||
:rows table})))
|
:rows table})))
|
||||||
)
|
)
|
||||||
|
|
||||||
(defn add-total-border [rows]
|
|
||||||
(map (fn [row]
|
|
||||||
(let [last-idx (dec (count row))]
|
|
||||||
(map-indexed
|
|
||||||
(fn [i cell]
|
|
||||||
(if (= i last-idx)
|
|
||||||
(let [borders (or (:border cell) [])]
|
|
||||||
(assoc cell :border (conj borders :left)))
|
|
||||||
cell))
|
|
||||||
row)))
|
|
||||||
rows))
|
|
||||||
|
|
||||||
(defn summarize-balance-sheet [pnl-data]
|
(defn summarize-balance-sheet [pnl-data]
|
||||||
(let [client-ids (set (map :client-id (:data pnl-data)))
|
(let [pnl-datas (for [client-id (set (map :client-id (:data pnl-data)))
|
||||||
client-count (count client-ids)
|
|
||||||
period-count (count (:periods (:args pnl-data)))
|
|
||||||
show-total? (and (> client-count 1) (= 1 period-count))
|
|
||||||
pnl-datas (for [client-id client-ids
|
|
||||||
p (:periods (:args pnl-data))]
|
p (:periods (:args pnl-data))]
|
||||||
(-> pnl-data
|
(-> pnl-data
|
||||||
(filter-client client-id)
|
(filter-client client-id)
|
||||||
(filter-period p)))
|
(filter-period p)))]
|
||||||
total-data (when show-total?
|
|
||||||
(-> pnl-data
|
|
||||||
(filter-period (first (:periods (:args pnl-data))))
|
|
||||||
(assoc :cell-args {:bold true})))
|
|
||||||
pnl-datas (concat pnl-datas (when total-data [total-data]))]
|
|
||||||
(let [table (-> []
|
(let [table (-> []
|
||||||
(into (detail-rows pnl-datas
|
(into (detail-rows pnl-datas
|
||||||
:assets
|
:assets
|
||||||
@@ -937,11 +912,10 @@
|
|||||||
(negate #{:cogs :payroll :controllable :fixed-overhead :ownership-controllable}))
|
(negate #{:cogs :payroll :controllable :fixed-overhead :ownership-controllable}))
|
||||||
pnl-datas)
|
pnl-datas)
|
||||||
"Retained Earnings")))
|
"Retained Earnings")))
|
||||||
table (if (and (> period-count 1)
|
table (if (and (> (count (:periods (:args pnl-data))) 1)
|
||||||
(:include-deltas (:args pnl-data)))
|
(:include-deltas (:args pnl-data)))
|
||||||
(append-deltas table)
|
(append-deltas table)
|
||||||
table)
|
table)]
|
||||||
table (if show-total? (add-total-border table) table)]
|
|
||||||
{:warning (warning-message pnl-data)
|
{:warning (warning-message pnl-data)
|
||||||
:header (balance-sheet-headers pnl-data)
|
:header (balance-sheet-headers pnl-data)
|
||||||
:rows table}))
|
:rows table}))
|
||||||
|
|||||||
@@ -265,8 +265,7 @@ NOTE: Please review the transactions we may have question for you here: https://
|
|||||||
[:div.notification.is-warning.is-light
|
[:div.notification.is-warning.is-light
|
||||||
(:warning report)])
|
(:warning report)])
|
||||||
[rtable/table {:widths (cond-> (into [30 ] (repeat 13 client-count))
|
[rtable/table {:widths (cond-> (into [30 ] (repeat 13 client-count))
|
||||||
(:include-comparison args) (into (repeat 13 (* 2 client-count)))
|
(:include-comparison args) (into (repeat 13 (* 2 client-count))))
|
||||||
(and (> client-count 1) (not (:include-comparison args))) (conj 13))
|
|
||||||
:click-event ::investigate-clicked
|
:click-event ::investigate-clicked
|
||||||
:table report}]]))
|
:table report}]]))
|
||||||
|
|
||||||
|
|||||||
@@ -1,2 +1,5 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
sudo docker run --rm -ti -v ~/dev/integreat/data/solr:/var/solr --network=bridge -p 8983:8983 679918342773.dkr.ecr.us-east-1.amazonaws.com/integreat-solr
|
sudo docker run --rm -ti -v ~/dev/integreat/data/solr:/var/solr --network=bridge -p 8983:8983 bryce-solr
|
||||||
|
#sudo podman container run --user 1000 --privileged --volume /home/notid/dev/integreat/data/solr:/var/solr -p 8983:8983 bryce-solr
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user