From f589b249082e62650d20baaaf1fcb238532428e7 Mon Sep 17 00:00:00 2001 From: Bryce Date: Wed, 23 Oct 2024 09:18:14 -0700 Subject: [PATCH] makes balance sheet with multiple dates easy. --- src/clj/auto_ap/ssr/ledger/balance_sheet.clj | 41 +++-------- src/cljc/auto_ap/ledger/reports.cljc | 77 ++++++++++++-------- 2 files changed, 55 insertions(+), 63 deletions(-) diff --git a/src/clj/auto_ap/ssr/ledger/balance_sheet.clj b/src/clj/auto_ap/ssr/ledger/balance_sheet.clj index fb27194a..53b78911 100644 --- a/src/clj/auto_ap/ssr/ledger/balance_sheet.clj +++ b/src/clj/auto_ap/ssr/ledger/balance_sheet.clj @@ -66,7 +66,7 @@ (def query-schema (mc/schema - [:maybe [:and [:map + [:maybe [:map [:client {:unspecified/value :all} [:or [:enum :all] @@ -77,19 +77,7 @@ [:vector {:coerce? true :decode/string (fn [s] (if (string? s) (str/split s #", ") s))} - 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))]]])) + clj-date-schema]] ]])) @@ -216,9 +204,10 @@ ;; 3. General cleanup of the patterns in run-balance-sheet ;; 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) (let [client (if (= :all client) (take 5 (:clients request)) client) + date (reverse (sort date )) client-ids (map :db/id client) _ (doseq [client-id client-ids] (assert-can-see-client (:identity request) client-id)) @@ -245,7 +234,6 @@ :period (coerce/to-date d)})) args (assoc (:query-params request) :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) 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.")) {: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 (when (and date client) (let [{:keys [client warning]} (maybe-trim-clients request client) @@ -287,7 +275,7 @@ :hx-swap "outerHTML" :hx-disabled-elt "find 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 (com/validated-inline-field {:label "Customers" :errors (fc/field-errors)} @@ -305,16 +293,7 @@ (com/multi-date-input {:placeholder "12/21/2020" :name (fc/field-name) :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"} "Run") (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.) 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 (-> [{:left-margin 10 :right-margin 10 :top-margin 15 :bottom-margin 15 :size :letter @@ -358,8 +338,7 @@ (conj (table->pdf report (cond-> (into [30 ] (repeat client-count 13)) - (or (:include-comparison (:query-params request)) - (:include-comparison (:form-params request))) (into (repeat (* 2 client-count) 13)))))) + (> (count date) 1) (into (repeat (* 2 client-count (dec (count date))) 13 )))))) output-stream) (.toByteArray output-stream))) diff --git a/src/cljc/auto_ap/ledger/reports.cljc b/src/cljc/auto_ap/ledger/reports.cljc index 0ac85209..a79ff6d3 100644 --- a/src/cljc/auto_ap/ledger/reports.cljc +++ b/src/cljc/auto_ap/ledger/reports.cljc @@ -6,6 +6,7 @@ [auto-ap.time-utils :refer [user-friendly-date]] [auto-ap.utils :refer [dollars-0? dollars=]] [clojure.string :as str] + [clj-time.coerce :as coerce] [auto-ap.time-utils :refer [user-friendly-date]] )] :cljs @@ -17,7 +18,9 @@ (defn date->str [d] #?(: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))) @@ -786,42 +789,52 @@ (defn balance-sheet-headers [pnl-data] - (cond-> [] - (> (count (set (map :client-id (:data pnl-data)))) 1) - (conj (into [{:value "Client"}] + (let [period-count (count (:periods (:args pnl-data)))] + (cond-> [] + (> (count (set (map :client-id (:data pnl-data)))) 1) + (conj (into [{:value "Client"}] - (mapcat identity - (for [client (set (map :client-id (:data pnl-data))) ] - (cond-> [{:value (str (-> pnl-data :client-codes (get client)))}] + (mapcat identity + (for [client (set (map :client-id (:data pnl-data))) ] + (cond-> [{:value (str (-> pnl-data :client-codes (get client)))}] - (> (count (:periods (:args pnl-data))) 1) - (into ["" ""])))))) - true - (conj (into [{:value "Period Ending"}] - - (mapcat identity - (for [client (set (map :client-id (:data pnl-data))) ] - (cond-> [{:value (date->str (:date (:args pnl-data)))}] - - (> (count (:periods (:args pnl-data))) 1) - (into [{:value (date->str (:comparison-date (:args pnl-data)))} - {:value "+/-"}])))))))) + (> period-count 1) + (into (apply concat (repeat (dec period-count) ["" ""])))))))) + true + (conj (into [{:value "Period Ending"}] + (for [client (set (map :client-id (:data pnl-data))) + [index p] (map vector (range) (:periods (:args pnl-data))) + :let [is-first? (= 0 index) + period-date (date->str p) + period-headers (if is-first? + [{:value period-date}] + [{:value period-date} + {:value "+/-"}])] + header period-headers] + header)))))) (defn append-deltas [table] (->> table - (map (fn [[title & pairs]] - (reduce - (fn [result [ a b]] - (into result - [a b (and (:value a) (:value b) - (number? (:value a)) (number? (:value b)) - {:border (:border b) - :format :dollar - :value (- (or (:value a) 0.0) - (or (:value b) 0.0))})])) - [title] - (partition 2 pairs)))))) + (map (fn [[title & values]] + (loop [result [title] + previous nil + [current :as values] values] + (if current + (recur + (cond-> result + true (conj current) + (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] (reduce @@ -889,7 +902,7 @@ (negate #{:cogs :payroll :controllable :fixed-overhead :ownership-controllable})) pnl-datas) "Retained Earnings"))) - table (if (> (count (:periods pnl-data)) 1) + table (if (> (count (:periods (:args pnl-data))) 1) (append-deltas table) table)] {:warning (warning-message pnl-data)