unifying reports even more.

This commit is contained in:
2022-03-29 18:02:13 -07:00
parent c9943bbae1
commit 17fde0dd16
3 changed files with 131 additions and 139 deletions

View File

@@ -167,31 +167,31 @@
report (l-reports/summarize-pnl pnl-data) report (l-reports/summarize-pnl pnl-data)
output-stream (ByteArrayOutputStream.)] output-stream (ByteArrayOutputStream.)]
(pdf/pdf (pdf/pdf
(into (-> [{: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 (cond
:size (cond (and (>= (count (-> pnl-data :args :periods)) 8 )
(and (>= (count (-> pnl-data :args :periods)) 8 ) (-> pnl-data :args :include-deltas))
(-> pnl-data :args :include-deltas)) :a2
:a2
(>= (count (-> pnl-data :args :periods)) 4 ) (>= (count (-> pnl-data :args :periods)) 4 )
:tabloid :tabloid
:else
:else :letter)
:letter) :orientation :landscape
:orientation :landscape :font {:size 6
:font {:size 6 :ttf-name "fonts/calibri-light.ttf"}}
:ttf-name "fonts/calibri-light.ttf"}} [:heading (str "Profit and Loss - " (str/join ", " (map :client/name clients)))]]
[:heading (str "Profit and Loss - " (str/join ", " (map :client/name clients)))]] (conj [:paragraph {:color [128 0 0] :size 9} (:warning report)])
(for [table (concat (:summaries report) (into
(:details report))] (for [table (concat (:summaries report)
(table->pdf table (:details report))]
(into [20] (take (dec (cell-count table)) (table->pdf table
(mapcat identity (into [20] (take (dec (cell-count table))
(repeat (mapcat identity
(if (-> pnl-data :args :include-deltas) (repeat
[13 6 13] (if (-> pnl-data :args :include-deltas)
[13 6])))))))) [13 6 13]
[13 6])))))))))
output-stream) output-stream)
(.toByteArray output-stream))) (.toByteArray output-stream)))

View File

@@ -1,9 +1,15 @@
(ns auto-ap.ledger.reports (ns auto-ap.ledger.reports
(:require #?@
[auto-ap.utils :refer [dollars-0?]] (:clj
#?(:cljs [auto-ap.views.utils :as au ] [(:require
:clj [auto-ap.time :as atime]))) [auto-ap.time :as atime]
[auto-ap.utils :refer [dollars-0?]]
[clojure.string :as str])]
:cljs
[(:require
[auto-ap.utils :refer [dollars-0?]]
[auto-ap.views.utils :as au]
[clojure.string :as str])]))
(defn date->str [d] (defn date->str [d]
#?(:clj #?(:clj
@@ -339,11 +345,26 @@
{:header (headers pnl-data title) {:header (headers pnl-data title)
:rows (combine-tables pnl-data table percent-of-sales deltas)})) :rows (combine-tables pnl-data table percent-of-sales deltas)}))
(defn warning-message [pnl-data]
(let [errors (->> pnl-data
:data
(filter (fn [{:keys [numeric-code]}]
(nil? numeric-code))))
error-count (count errors)]
(when (> error-count 0)
(str "This report does not include "
(str/join ", "
(map #(str (:count %) " unresolved ledger entries for " (if (str/blank? (:location %))
" all locations"
(:location %)))
errors))))))
(defn summarize-pnl [pnl-data] (defn summarize-pnl [pnl-data]
{:summaries (for [[client-id location] (locations (:data pnl-data))] {:warning (warning-message pnl-data)
:summaries (for [[client-id location] (locations (:data pnl-data))]
(location-summary-table (-> pnl-data (location-summary-table (-> pnl-data
(filter-client client-id) (filter-client client-id)
(filter-location location)) (filter-location location))
(str (-> pnl-data :clients-by-id (get client-id)) " (" location ") Summary"))) (str (-> pnl-data :clients-by-id (get client-id)) " (" location ") Summary")))
:details (for [[client-id location] (locations (:data pnl-data))] :details (for [[client-id location] (locations (:data pnl-data))]
(location-detail-table (-> pnl-data (location-detail-table (-> pnl-data

View File

@@ -37,9 +37,14 @@
(defn and-last-year [[from to]] (defn and-last-year [{:keys [start end] :as p1}]
[[from to] [p1
[(t/minus from (t/years 1)) (t/minus to (t/years 1))]]) {:start (t/minus start (t/years 1))
:end (t/minus end (t/years 1))}])
(defn encode-period [p]
{:start (date->str (:start p) standard)
:end (date->str (:end p) standard)})
;; SUBS ;; SUBS
@@ -49,18 +54,6 @@
(fn [db] (fn [db]
(-> db ::ledger-list-active?))) (-> db ::ledger-list-active?)))
(re-frame/reg-sub
::uncategorized-accounts
:<- [::forms/form ::form]
(fn [db [_ ]]
(->> (get-in db [:report :periods ])
(mapcat :accounts)
(map #(update % :amount js/parseFloat))
(filter (fn [{:keys [account-type location numeric-code]}]
(nil? numeric-code))))))
(re-frame/reg-event-db (re-frame/reg-event-db
::received ::received
[(forms/in-form ::form)] [(forms/in-form ::form)]
@@ -82,14 +75,12 @@
:owns-state {:single ::page} :owns-state {:single ::page}
:query-obj {:venia/queries [[:profit-and-loss :query-obj {:venia/queries [[:profit-and-loss
{:client-ids (map :id (:clients (:data db))) {:client-ids (map :id (:clients (:data db)))
:periods (mapv (fn [[start end] ] {:start (date->str start standard) :end (date->str end standard)} ) :periods (mapv encode-period (:periods (:data db)))}
(:periods (:data db)))}
[[:periods [[:accounts [:name :amount :client_id :account-type :id :count :numeric-code :location]]]]]]]} [[:periods [[:accounts [:name :amount :client_id :account-type :id :count :numeric-code :location]]]]]]]}
:on-success [::received]} :on-success [::received]}
:set-uri-params {:periods (mapv (fn [[start end title]] :set-uri-params {:periods (mapv
[(date->str start standard) encode-period
(date->str end standard)]) (:periods (:data db)))
(:periods (:data db)))
:clients (mapv #(select-keys % [:name :id]) (:clients (:data db))) } :clients (mapv #(select-keys % [:name :id]) (:clients (:data db))) }
:db (dissoc db :report)}))) :db (dissoc db :report)})))
@@ -129,14 +120,10 @@ Please download it by clicking this link: " report-url)))
:query-obj {:venia/queries [[:profit-and-loss-pdf :query-obj {:venia/queries [[:profit-and-loss-pdf
{:client-ids (map :id (:clients (:data db))) {:client-ids (map :id (:clients (:data db)))
:include-deltas (:include-deltas (:data db)) :include-deltas (:include-deltas (:data db))
:periods (mapv (fn [[start end] ] {:start (date->str start standard) :end (date->str end standard)} ) :periods (mapv encode-period (:periods (:data db)))}
(:periods (:data db)))}
[:report_url]]]} [:report_url]]]}
:on-success [::received-pdf]} :on-success [::received-pdf]}
:set-uri-params {:periods (mapv (fn [[start end title]] :set-uri-params {:periods (mapv encode-period (:periods (:data db)))
[(date->str start standard)
(date->str end standard)])
(:periods (:data db)))
:clients (mapv #(select-keys % [:name :id]) (:clients (:data db))) } :clients (mapv #(select-keys % [:name :id]) (:clients (:data db))) }
:db (dissoc db :report)}))) :db (dissoc db :report)})))
@@ -368,14 +355,14 @@ Please download it by clicking this link: " report-url)))
(let [today (or (some-> (:thirteen-periods-end data) (str->date standard)) (let [today (or (some-> (:thirteen-periods-end data) (str->date standard))
(local-today))] (local-today))]
(into (into
[[(t/plus (t/minus today (t/weeks (* 13 4))) [{:start (t/plus (t/minus today (t/weeks (* 13 4)))
(t/days 1)) (t/days 1))
today :end today
"Total"]] :title "Total"}]
(for [i (range 13)] (for [i (range 13)]
[(t/plus (t/minus today (t/weeks (* (inc i) 4))) {:start (t/plus (t/minus today (t/weeks (* (inc i) 4)))
(t/days 1)) (t/days 1))
(t/minus today (t/weeks (* i 4)))]))) :end (t/minus today (t/weeks (* i 4)))})))
[:selected-period] "13 periods"])} [:selected-period] "13 periods"])}
"13 periods"]]]] "13 periods"]]]]
@@ -385,8 +372,7 @@ Please download it by clicking this link: " report-url)))
(raw-field (raw-field
[date-picker-friendly {:placeholder "End date" [date-picker-friendly {:placeholder "End date"
:type "date" :type "date"
:field [:twelve-periods-end]}]) :field [:twelve-periods-end]}])]
]
[:div.control [:div.control
[:a.button [:a.button
{:class (when (= selected-period "12 months") "is-active") {:class (when (= selected-period "12 months") "is-active")
@@ -397,17 +383,16 @@ Please download it by clicking this link: " report-url)))
(local-today)) (local-today))
this-month (t/local-date (t/year end-date) this-month (t/local-date (t/year end-date)
(t/month end-date) (t/month end-date)
1) 1)]
] (into
(into [{:start (t/minus this-month (t/months 11))
[[(t/minus this-month (t/months 11)) :end (t/minus (t/plus this-month (t/months 1))
(t/minus (t/plus this-month (t/months 1)) (t/days 1))
(t/days 1)) :title "Total"}]
"Total"]]
(for [i (range 12)] (for [i (range 12)]
[(t/minus this-month (t/months (- 11 i))) {:start (t/minus this-month (t/months (- 11 i)))
(t/minus (t/minus this-month (t/months (- 10 i))) :end (t/minus (t/minus this-month (t/months (- 10 i)))
(t/days 1))]))) (t/days 1))})))
[:selected-period] "12 months"])} [:selected-period] "12 months"])}
"12 months"]]]] "12 months"]]]]
@@ -421,21 +406,21 @@ Please download it by clicking this link: " report-url)))
(if (= 7 (t/day-of-week current)) (if (= 7 (t/day-of-week current))
current current
(recur (t/minus current (t/period :days 1)))))] (recur (t/minus current (t/period :days 1)))))]
(and-last-year {:start (t/minus last-sunday (t/period :days 6))
(and-last-year [(t/minus last-sunday (t/period :days 6)) last-sunday])) :end last-sunday}))
[:selected-period] "Last week"])} [:selected-period] "Last week"])}
"Last week"]] "Last week"]]
[:div.control [:div.control
[:a.button [:a.button
{:class (when (= selected-period "Week to date") "is-active") {:class (when (= selected-period "Week to date") "is-active")
:on-click (dispatch-event :on-click (dispatch-event
[::change [::change
[:periods] [:periods]
(and-last-year [(loop [current (local-today)] (and-last-year {:start (loop [current (local-today)]
(if (= 1 (t/day-of-week current)) (if (= 1 (t/day-of-week current))
current current
(recur (t/minus current (t/period :days 1))))) (recur (t/minus current (t/period :days 1)))))
(local-today)]) :end (local-today)})
[:selected-period] "Week to date"])} [:selected-period] "Week to date"])}
"Week to date"]] "Week to date"]]
[:div.control [:div.control
@@ -445,14 +430,14 @@ Please download it by clicking this link: " report-url)))
[::change [::change
[:periods] [:periods]
(and-last-year [(t/minus (t/local-date (t/year (local-today)) (and-last-year {:start (t/minus (t/local-date (t/year (local-today))
(t/month (local-today)) (t/month (local-today))
1) 1)
(t/period :months 1)) (t/period :months 1))
(t/minus (t/local-date (t/year (local-today)) :end (t/minus (t/local-date (t/year (local-today))
(t/month (local-today)) (t/month (local-today))
1) 1)
(t/period :days 1))]) (t/period :days 1))})
[:selected-period] "Last Month"])} [:selected-period] "Last Month"])}
"Last Month"]] "Last Month"]]
[:div.control [:div.control
@@ -461,10 +446,10 @@ Please download it by clicking this link: " report-url)))
:on-click (dispatch-event :on-click (dispatch-event
[::change [::change
[:periods] [:periods]
(and-last-year [(t/local-date (t/year (local-today)) (and-last-year {:start (t/local-date (t/year (local-today))
(t/month (local-today)) (t/month (local-today))
1) 1)
(local-today)]) :end (local-today)})
[:selected-period] "Month to date"] [:selected-period] "Month to date"]
)} )}
"Month to date"]] "Month to date"]]
@@ -474,8 +459,9 @@ Please download it by clicking this link: " report-url)))
:on-click (dispatch-event :on-click (dispatch-event
[::change [::change
[:periods] [:periods]
(and-last-year [(t/local-date (t/year (local-today)) 1 1) (and-last-year {:start (t/local-date (t/year (local-today)) 1 1)
(local-today)]) :end
(local-today)})
[:selected-period] "Year to date"])} [:selected-period] "Year to date"])}
"Year to date"]] "Year to date"]]
[:div.control [:div.control
@@ -484,8 +470,8 @@ Please download it by clicking this link: " report-url)))
:on-click (dispatch-event :on-click (dispatch-event
[::change [::change
[:periods] [:periods]
[[(t/local-date (dec (t/year (local-today))) 1 1) [{:start (t/local-date (dec (t/year (local-today))) 1 1)
(t/local-date (dec (t/year (local-today))) 12 31)]] :end (t/local-date (dec (t/year (local-today))) 12 31)}]
[:selected-period] "Last Calendar year"])} [:selected-period] "Last Calendar year"])}
"Last calendar year"]] "Last calendar year"]]
[:div.control [:div.control
@@ -494,15 +480,15 @@ Please download it by clicking this link: " report-url)))
:on-click (dispatch-event :on-click (dispatch-event
[::change [::change
[:periods] [:periods]
(and-last-year [(t/plus (t/minus (local-today) (t/period :years 1)) (and-last-year {:start (t/plus (t/minus (local-today) (t/period :years 1))
(t/period :days 1)) (t/period :days 1))
(local-today)]) :end (local-today)})
[:selected-period] "Full year"])} [:selected-period] "Full year"])}
"Full year"]]] "Full year"]]]
[:div [:div
[:div.field [:div.field
[:label.checkbox [:label.checkbox
(raw-field (raw-field
[:input {:type "checkbox" [:input {:type "checkbox"
:field [:show-advanced?]}]) :field [:show-advanced?]}])
" Show Advanced"]]] " Show Advanced"]]]
@@ -515,13 +501,13 @@ Please download it by clicking this link: " report-url)))
[:p.help "From"] [:p.help "From"]
(raw-field (raw-field
[date-picker-friendly {:type "date" [date-picker-friendly {:type "date"
:field [:periods i 0]}])] :field [:periods i :start]}])]
[:div.control [:div.control
[:p.help "To"] [:p.help "To"]
(raw-field (raw-field
[date-picker-friendly {:type "date" [date-picker-friendly {:type "date"
:field [:periods i 1]}])]])))]]] :field [:periods i :end]}])]])))]]]
[:div.level-item [:div.level-item
[:div [:div
@@ -545,14 +531,7 @@ Please download it by clicking this link: " report-url)))
(reset! !box el)))}]])))) (reset! !box el)))}]]))))
(defn pnl-report [{:keys [args report-data]}] (defn pnl-report [{:keys [args report-data]}]
(let [args (update args :periods (let [pnl-data (->> report-data
(fn [p]
(mapv (fn [[start end] ]
{:start start
:end end} )
p)))
pnl-data (->> report-data
:periods :periods
(mapcat (fn [p1 p2] (mapcat (fn [p1 p2]
(map (map
@@ -562,7 +541,6 @@ Please download it by clicking this link: " report-url)))
) )
(:accounts p2))) (:accounts p2)))
(:periods args))) (:periods args)))
unresolved-accounts @(re-frame/subscribe [::uncategorized-accounts])
client-names (->> @(re-frame/subscribe [::subs/clients-by-id]) client-names (->> @(re-frame/subscribe [::subs/clients-by-id])
(map (fn [[k v]] (map (fn [[k v]]
[k (:name v)])) [k (:name v)]))
@@ -571,13 +549,9 @@ Please download it by clicking this link: " report-url)))
report (l-reports/summarize-pnl pnl-data)] report (l-reports/summarize-pnl pnl-data)]
[:div [:div
[:h1.title "Profit and Loss - " (str/join ", " (map :name (:clients args)))] [:h1.title "Profit and Loss - " (str/join ", " (map :name (:clients args)))]
(when (seq unresolved-accounts) (when (:warning report)
[:div.notification.is-warning.is-light [:div.notification.is-warning.is-light
"This report does not include " (str/join ", " (:warning report)])
(map #(str (:count %) " unresolved ledger entries for " (if (str/blank? (:location %))
" all locations"
(:location %)))
unresolved-accounts))])
(for [[index table] (map vector (range) (concat (:summaries report) (for [[index table] (map vector (range) (concat (:summaries report)
(:details report)))] (:details report)))]
^{:key index} ^{:key index}
@@ -592,18 +566,18 @@ Please download it by clicking this link: " report-url)))
(defn profit-and-loss-content [] (defn profit-and-loss-content []
(let [status @(re-frame/subscribe [::status/single ::page]) (let [status @(re-frame/subscribe [::status/single ::page])
{:keys [data report active? error id]} @(re-frame/subscribe [::forms/form ::form]) {:keys [data report]} @(re-frame/subscribe [::forms/form ::form])
{:keys [form-inline field raw-field error-notification submit-button ]} pnl-form {:keys [form-inline]} pnl-form]
] [:div
(form-inline {} (form-inline {}
[:div [:div
[status/status-notification {:statuses [[::status/single ::page]]}] [status/status-notification {:statuses [[::status/single ::page]]}]
[report-controls pnl-form] [report-controls pnl-form]])
[status/big-loader status] [status/big-loader status]
(when (and (not= :loading (:state status)) (when (and (not= :loading (:state status))
report) report)
[pnl-report {:report-data report [pnl-report {:report-data report
:args data}])]))) :args data}])]))
(re-frame/reg-event-fx (re-frame/reg-event-fx
::unmounted-pnl ::unmounted-pnl
@@ -617,11 +591,8 @@ Please download it by clicking this link: " report-url)))
{:db (forms/start-form db ::form {:periods (->> qp {:db (forms/start-form db ::form {:periods (->> qp
:periods :periods
(mapv (fn [period] (mapv (fn [period]
(mapv {:start (str->date (:start period) standard)
(fn [dt] :end (str->date (:end period) standard)})))
(str->date dt standard))
period))))
:clients (or (:clients qp) :clients (or (:clients qp)
[(some-> @(re-frame/subscribe [::subs/client]) (select-keys [:name :id]))]) [(some-> @(re-frame/subscribe [::subs/client]) (select-keys [:name :id]))])
:include-deltas true}) :include-deltas true})