makes balance sheet with multiple dates easy.
This commit is contained in:
@@ -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)))
|
||||||
|
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
Reference in New Issue
Block a user