makes balance sheet with multiple dates easy.

This commit is contained in:
2024-10-23 09:18:14 -07:00
parent 3da8bf054f
commit f589b24908
2 changed files with 55 additions and 63 deletions

View File

@@ -66,7 +66,7 @@
(def query-schema (mc/schema (def query-schema (mc/schema
[:maybe [:and [:map [:maybe [:map
[:client {:unspecified/value :all} [:client {:unspecified/value :all}
[:or [:or
[:enum :all] [:enum :all]
@@ -77,19 +77,7 @@
[:vector {:coerce? true [:vector {:coerce? true
:decode/string (fn [s] (if (string? s) (str/split s #", ") :decode/string (fn [s] (if (string? s) (str/split s #", ")
s))} s))}
clj-date-schema]] clj-date-schema]] ]]))
[:comparison-date {:optional true}
[:maybe clj-date-schema]]
[:include-comparison {:optional true :default false}
[ :boolean {:decode/string {:enter #(if (= % "on") true
(boolean %))}}]]]
[:fn {:error/message "required"
:error/path [:comparison-date]}
(fn [x]
(if (and (not (:comparison-date x))
(:include-comparison x))
false
true))]]]))
@@ -216,9 +204,10 @@
;; 3. General cleanup of the patterns in run-balance-sheet ;; 3. General cleanup of the patterns in run-balance-sheet
;; 4. Review ledger dialog ;; 4. Review ledger dialog
(defn get-report [{ {:keys [date comparison-date include-comparison client] :as qp} :query-params :as request}] (defn get-report [{ {:keys [date client] :as qp} :query-params :as request}]
(when (and date client) (when (and date client)
(let [client (if (= :all client) (take 5 (:clients request)) client) (let [client (if (= :all client) (take 5 (:clients request)) client)
date (reverse (sort date ))
client-ids (map :db/id client) client-ids (map :db/id client)
_ (doseq [client-id client-ids] _ (doseq [client-id client-ids]
(assert-can-see-client (:identity request) client-id)) (assert-can-see-client (:identity request) client-id))
@@ -245,7 +234,6 @@
:period (coerce/to-date d)})) :period (coerce/to-date d)}))
args (assoc (:query-params request) args (assoc (:query-params request)
:periods (map coerce/to-date (filter identity date))) :periods (map coerce/to-date (filter identity date)))
_ (println "ARGS ARE" args)
clients (pull-many (dc/db conn) [:client/code :client/name :db/id] client-ids) clients (pull-many (dc/db conn) [:client/code :client/name :db/id] client-ids)
pnl-data (l-reports/->PNLData args data (by :db/id :client/code clients)) pnl-data (l-reports/->PNLData args data (by :db/id :client/code clients))
@@ -261,7 +249,7 @@
(assoc :warning "You requested a report with more than 20 clients. This report will only contain the first 20.")) (assoc :warning "You requested a report with more than 20 clients. This report will only contain the first 20."))
{:client client})) {:client client}))
(defn balance-sheet* [{ {:keys [date comparison-date include-comparison client] } :query-params :as request}] (defn balance-sheet* [{ {:keys [date client] } :query-params :as request}]
[:div#report [:div#report
(when (and date client) (when (and date client)
(let [{:keys [client warning]} (maybe-trim-clients request client) (let [{:keys [client warning]} (maybe-trim-clients request client)
@@ -287,7 +275,7 @@
:hx-swap "outerHTML" :hx-swap "outerHTML"
:hx-disabled-elt "find fieldset"} :hx-disabled-elt "find fieldset"}
[:fieldset [:fieldset
[:div.flex.gap-8 {:x-data (hx/json {:comparison (boolean (:include-comparison params))})} [:div.flex.gap-8 {:x-data (hx/json {})}
(fc/with-field :client (fc/with-field :client
(com/validated-inline-field (com/validated-inline-field
{:label "Customers" :errors (fc/field-errors)} {:label "Customers" :errors (fc/field-errors)}
@@ -305,16 +293,7 @@
(com/multi-date-input {:placeholder "12/21/2020" (com/multi-date-input {:placeholder "12/21/2020"
:name (fc/field-name) :name (fc/field-name)
:value (fc/field-value)}))) :value (fc/field-value)})))
(fc/with-field :include-comparison
(com/toggle {:x-model "comparison" :name (fc/field-name) :checked (boolean (fc/field-value))} "Compare"))
[:div (hx/alpine-appear {:x-show "comparison"})
(fc/with-field :comparison-date
(com/validated-inline-field {:label "Previous Date"
:errors (fc/field-errors)}
(com/date-input {:placeholder "12/21/2020"
:name (fc/field-name)
:value (some-> (or (fc/field-value) (t/plus (t/now) (t/years -1)))
(atime/unparse-local atime/normal-date))})))]
(com/button {:color :primary :class "w-32"} (com/button {:color :primary :class "w-32"}
"Run") "Run")
(com/button {:formaction (bidi.bidi/path-for ssr-routes/only-routes ::route/export-balance-sheet) } "Export PDF")]]] ] (com/button {:formaction (bidi.bidi/path-for ssr-routes/only-routes ::route/export-balance-sheet) } "Export PDF")]]] ]
@@ -345,7 +324,8 @@
(let [ output-stream (ByteArrayOutputStream.) (let [ output-stream (ByteArrayOutputStream.)
client-count (count (or (seq (:client (:query-params request))) client-count (count (or (seq (:client (:query-params request)))
(seq (:client (:form-params request)))))] (seq (:client (:form-params request)))))
date (:date (:query-params request))]
(pdf/pdf (pdf/pdf
(-> [{:left-margin 10 :right-margin 10 :top-margin 15 :bottom-margin 15 (-> [{:left-margin 10 :right-margin 10 :top-margin 15 :bottom-margin 15
:size :letter :size :letter
@@ -358,8 +338,7 @@
(conj (conj
(table->pdf report (table->pdf report
(cond-> (into [30 ] (repeat client-count 13)) (cond-> (into [30 ] (repeat client-count 13))
(or (:include-comparison (:query-params request)) (> (count date) 1) (into (repeat (* 2 client-count (dec (count date))) 13 ))))))
(:include-comparison (:form-params request))) (into (repeat (* 2 client-count) 13))))))
output-stream) output-stream)
(.toByteArray output-stream))) (.toByteArray output-stream)))

View File

@@ -6,6 +6,7 @@
[auto-ap.time-utils :refer [user-friendly-date]] [auto-ap.time-utils :refer [user-friendly-date]]
[auto-ap.utils :refer [dollars-0? dollars=]] [auto-ap.utils :refer [dollars-0? dollars=]]
[clojure.string :as str] [clojure.string :as str]
[clj-time.coerce :as coerce]
[auto-ap.time-utils :refer [user-friendly-date]] [auto-ap.time-utils :refer [user-friendly-date]]
)] )]
:cljs :cljs
@@ -17,7 +18,9 @@
(defn date->str [d] (defn date->str [d]
#?(:clj #?(:clj
(atime/unparse-local d atime/normal-date) (if (inst? d)
(atime/unparse-local (coerce/to-date-time d) atime/normal-date)
(atime/unparse-local d atime/normal-date))
:cljs (au/date->str d au/pretty))) :cljs (au/date->str d au/pretty)))
@@ -786,42 +789,52 @@
(defn balance-sheet-headers [pnl-data] (defn balance-sheet-headers [pnl-data]
(cond-> [] (let [period-count (count (:periods (:args pnl-data)))]
(> (count (set (map :client-id (:data pnl-data)))) 1) (cond-> []
(conj (into [{:value "Client"}] (> (count (set (map :client-id (:data pnl-data)))) 1)
(conj (into [{:value "Client"}]
(mapcat identity (mapcat identity
(for [client (set (map :client-id (:data pnl-data))) ] (for [client (set (map :client-id (:data pnl-data))) ]
(cond-> [{:value (str (-> pnl-data :client-codes (get client)))}] (cond-> [{:value (str (-> pnl-data :client-codes (get client)))}]
(> (count (:periods (:args pnl-data))) 1) (> period-count 1)
(into ["" ""])))))) (into (apply concat (repeat (dec period-count) ["" ""]))))))))
true true
(conj (into [{:value "Period Ending"}] (conj (into [{:value "Period Ending"}]
(for [client (set (map :client-id (:data pnl-data)))
(mapcat identity [index p] (map vector (range) (:periods (:args pnl-data)))
(for [client (set (map :client-id (:data pnl-data))) ] :let [is-first? (= 0 index)
(cond-> [{:value (date->str (:date (:args pnl-data)))}] period-date (date->str p)
period-headers (if is-first?
(> (count (:periods (:args pnl-data))) 1) [{:value period-date}]
(into [{:value (date->str (:comparison-date (:args pnl-data)))} [{:value period-date}
{:value "+/-"}])))))))) {:value "+/-"}])]
header period-headers]
header))))))
(defn append-deltas [table] (defn append-deltas [table]
(->> table (->> table
(map (fn [[title & pairs]] (map (fn [[title & values]]
(reduce (loop [result [title]
(fn [result [ a b]] previous nil
(into result [current :as values] values]
[a b (and (:value a) (:value b) (if current
(number? (:value a)) (number? (:value b)) (recur
{:border (:border b) (cond-> result
:format :dollar true (conj current)
:value (- (or (:value a) 0.0)
(or (:value b) 0.0))})]))
[title]
(partition 2 pairs))))))
(and (:value current) (:value previous)
(number? (:value current)) (number? (:value previous))
(= (:client-id (:filters previous))
(:client-id (:filters current))))
(conj {:border (:border previous)
:format :dollar
:value (- (or (:value current) 0.0)
(or (:value previous) 0.0))}))
current
(rest values))
result))))))
#_(defn summarize-balance-sheet [pnl-data] #_(defn summarize-balance-sheet [pnl-data]
(reduce (reduce
@@ -889,7 +902,7 @@
(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 (> (count (:periods pnl-data)) 1) table (if (> (count (:periods (:args pnl-data))) 1)
(append-deltas table) (append-deltas table)
table)] table)]
{:warning (warning-message pnl-data) {:warning (warning-message pnl-data)