Enables Cash flows
This commit is contained in:
@@ -10,7 +10,7 @@
|
||||
[auto-ap.graphql.utils
|
||||
:refer [->graphql <-graphql assert-admin assert-can-see-client result->page]]
|
||||
[auto-ap.parse.util :as parse]
|
||||
[auto-ap.pdf.ledger :refer [print-balance-sheet print-pnl print-journal-detail-report]]
|
||||
[auto-ap.pdf.ledger :refer [print-balance-sheet print-pnl print-journal-detail-report print-cash-flows]]
|
||||
[auto-ap.utils :refer [by dollars= heartbeat]]
|
||||
[clj-time.coerce :as coerce]
|
||||
[clj-time.core :as t]
|
||||
@@ -240,6 +240,11 @@
|
||||
|
||||
(->graphql result)))
|
||||
|
||||
(defn cash-flows-pdf [context args value]
|
||||
(let [data (get-profit-and-loss context args value)
|
||||
result (print-cash-flows (:id context) args data)]
|
||||
(->graphql result)))
|
||||
|
||||
(defn balance-sheet-pdf [context args value]
|
||||
(let [data (get-balance-sheet context args value)
|
||||
result (print-balance-sheet (:id context) args data)]
|
||||
@@ -804,6 +809,14 @@
|
||||
:column_per_location {:type 'Boolean}}
|
||||
:resolve :profit-and-loss-pdf}
|
||||
|
||||
:cash_flows_pdf {:type :report_pdf
|
||||
:args {:client_id {:type :id}
|
||||
:client_ids {:type '(list :id)}
|
||||
:periods {:type '(list :date_range)}
|
||||
:include_deltas {:type 'Boolean}
|
||||
:column_per_location {:type 'Boolean}}
|
||||
:resolve :cash-flows-pdf}
|
||||
|
||||
:balance_sheet_pdf {:type :report_pdf
|
||||
:args {:client_id {:type :id}
|
||||
:include_comparison {:type 'Boolean}
|
||||
@@ -884,6 +897,7 @@
|
||||
:get-balance-sheet get-balance-sheet
|
||||
:get-profit-and-loss get-profit-and-loss
|
||||
:profit-and-loss-pdf profit-and-loss-pdf
|
||||
:cash-flows-pdf cash-flows-pdf
|
||||
:journal-detail-report-pdf journal-detail-report-pdf
|
||||
:balance-sheet-pdf balance-sheet-pdf
|
||||
:get-ledger-csv get-ledger-csv
|
||||
|
||||
@@ -180,7 +180,6 @@
|
||||
(.toByteArray output-stream)))
|
||||
|
||||
(defn make-pnl [args data]
|
||||
|
||||
(let [data (<-graphql data)
|
||||
args (<-graphql args)
|
||||
clients (d/pull-many (d/db conn) '[:client/code :client/name :db/id] (:client-ids args))
|
||||
@@ -226,6 +225,52 @@
|
||||
output-stream)
|
||||
(.toByteArray output-stream)))
|
||||
|
||||
(defn make-cash-flows [args data]
|
||||
(let [data (<-graphql data)
|
||||
args (<-graphql args)
|
||||
clients (d/pull-many (d/db conn) '[:client/code :client/name :db/id] (:client-ids args))
|
||||
data (->> data
|
||||
:periods
|
||||
(mapcat (fn [p1 p2]
|
||||
(map
|
||||
(fn [a]
|
||||
(assoc a :period p1)
|
||||
)
|
||||
(:accounts p2))
|
||||
)
|
||||
(:periods args)))
|
||||
pnl-data (l-reports/->PNLData args data (by :db/id :client/code clients))
|
||||
report (l-reports/summarize-cash-flows pnl-data)
|
||||
output-stream (ByteArrayOutputStream.)]
|
||||
(pdf/pdf
|
||||
(-> [{:left-margin 10 :right-margin 10 :top-margin 5 :bottom-margin 15
|
||||
:size (cond
|
||||
(and (>= (count (-> pnl-data :args :periods)) 8 )
|
||||
(-> pnl-data :args :include-deltas))
|
||||
:a2
|
||||
|
||||
(>= (count (-> pnl-data :args :periods)) 4 )
|
||||
:tabloid
|
||||
:else
|
||||
:letter)
|
||||
:orientation :landscape
|
||||
:font {:size 6
|
||||
:ttf-name "fonts/calibri-light.ttf"}}
|
||||
[:heading (str "Statement of Cash Flows - " (str/join ", " (map :client/name clients)))]]
|
||||
(conj [:paragraph {:color [128 0 0] :size 9} (:warning report)])
|
||||
(into
|
||||
(for [table (concat (:summaries report)
|
||||
(:details report))]
|
||||
(table->pdf table
|
||||
(into [20] (take (dec (cell-count table))
|
||||
(mapcat identity
|
||||
(repeat
|
||||
(if (-> pnl-data :args :include-deltas)
|
||||
[13 6 13]
|
||||
[13 6])))))))))
|
||||
output-stream)
|
||||
(.toByteArray output-stream)))
|
||||
|
||||
(defn make-journal-detail-report [args data]
|
||||
|
||||
(println args)
|
||||
@@ -258,6 +303,16 @@
|
||||
names (str/replace (->> args :client_ids (d/pull-many (d/db conn) [:client/name]) (map :client/name) (str/join "-")) #" " "_" )]
|
||||
(format "Profit-and-loss-%s-to-%s-for-%s" min-date max-date names)))
|
||||
|
||||
(defn cash-flows-args->name [args]
|
||||
(let [min-date (atime/unparse-local
|
||||
(->> args :periods (map :start) first)
|
||||
atime/iso-date)
|
||||
max-date (atime/unparse-local
|
||||
(->> args :periods (map :end) last)
|
||||
atime/iso-date)
|
||||
names (str/replace (->> args :client_ids (d/pull-many (d/db conn) [:client/name]) (map :client/name) (str/join "-")) #" " "_" )]
|
||||
(format "Cash-flows-%s-to-%s-for-%s" min-date max-date names)))
|
||||
|
||||
(defn journal-detail-args->name [args]
|
||||
(println args)
|
||||
(let [min-date (atime/unparse-local
|
||||
@@ -297,6 +352,27 @@
|
||||
{:report/name name
|
||||
:report/url url }))
|
||||
|
||||
(defn print-cash-flows [user args data]
|
||||
(let [uuid (str (UUID/randomUUID))
|
||||
pdf-data (make-cash-flows args data)
|
||||
name (cash-flows-args->name args)
|
||||
key (str "reports/cash-flows/" uuid "/" name ".pdf")
|
||||
url (str "http://" (:data-bucket env) ".s3-website-us-east-1.amazonaws.com/" key)]
|
||||
(s3/put-object :bucket-name (:data-bucket env)
|
||||
:key key
|
||||
:input-stream (io/make-input-stream pdf-data {})
|
||||
:metadata {:content-length (count pdf-data)
|
||||
:content-type "application/pdf"})
|
||||
@(d/transact conn
|
||||
[{:report/name name
|
||||
:report/client (:client_ids args)
|
||||
:report/key key
|
||||
:report/url url
|
||||
:report/creator (:user user)
|
||||
:report/created (java.util.Date.)}])
|
||||
{:report/name name
|
||||
:report/url url }))
|
||||
|
||||
(defn print-balance-sheet [user args data]
|
||||
(let [uuid (str (UUID/randomUUID))
|
||||
pdf-data (make-balance-sheet args data)
|
||||
|
||||
@@ -111,11 +111,11 @@ NOTE: Please review the transactions we may have question for you here: https://
|
||||
{:dispatch [::modal/modal-requested {:title "Your report is ready"
|
||||
:body [:div
|
||||
[:div "Click "
|
||||
[:a {:href (-> result :profit-and-loss-pdf :url) :target "_new"} "here"] " to view it."]
|
||||
[:a {:href (-> result :cash-flows-pdf :url) :target "_new"} "here"] " to view it."]
|
||||
(when (and single-client? (seq client-emails))
|
||||
[:div "Once you've confirmed you're happy with it, click "
|
||||
[:a {:href (str "mailto:" (str/join ";" (map :email client-emails)) "?body=" (email-body (-> result :profit-and-loss-pdf :url))
|
||||
"&subject=" (-> result :profit-and-loss-pdf :name) " is ready")}
|
||||
[:a {:href (str "mailto:" (str/join ";" (map :email client-emails)) "?body=" (email-body (-> result :cash-flows-pdf :url))
|
||||
"&subject=" (-> result :cash-flows-pdf :name) " is ready")}
|
||||
"here"] " to open your email client and to send it to " (str/join "," (map (fn [e]
|
||||
(str (:email e) " (" (:description e) ")"))
|
||||
client-emails)) "."])]}]})))
|
||||
@@ -125,7 +125,7 @@ NOTE: Please review the transactions we may have question for you here: https://
|
||||
(fn [{:keys [db user]}]
|
||||
(cond-> {:graphql {:token user
|
||||
:owns-state {:single ::page}
|
||||
:query-obj {:venia/queries [[:profit-and-loss-pdf
|
||||
:query-obj {:venia/queries [[:cash-flows-pdf
|
||||
{:client-ids (map (comp :id :client) (:clients (:data db)))
|
||||
:include-deltas (:include-deltas (:data db))
|
||||
:column-per-location (:column-per-location (:data db))
|
||||
@@ -428,7 +428,7 @@ NOTE: Please review the transactions we may have question for you here: https://
|
||||
:table table}]]))
|
||||
|
||||
|
||||
(defn profit-and-loss-content []
|
||||
(defn cash-flows-content []
|
||||
(let [status @(re-frame/subscribe [::status/single ::page])
|
||||
{:keys [data report]} @(re-frame/subscribe [::forms/form ::form])]
|
||||
[:div
|
||||
@@ -472,7 +472,7 @@ NOTE: Please review the transactions we may have question for you here: https://
|
||||
|
||||
(defn cash-flows-page []
|
||||
(reagent/create-class
|
||||
{:display-name "profit-and-loss-page"
|
||||
{:display-name "cash-flows-page"
|
||||
:component-did-mount #(re-frame/dispatch [::mounted-pnl])
|
||||
:component-will-unmount #(re-frame/dispatch [::unmounted-pnl])
|
||||
:reagent-render
|
||||
@@ -482,7 +482,7 @@ NOTE: Please review the transactions we may have question for you here: https://
|
||||
(if (not= "manager" (:user/role @user))
|
||||
[side-bar-layout
|
||||
{:side-bar [ledger-side-bar]
|
||||
:main [profit-and-loss-content]
|
||||
:main [cash-flows-content]
|
||||
:right-side-bar [appearing-side-bar
|
||||
{:visible? ledger-list-active?}
|
||||
[ledger-list]]}]
|
||||
|
||||
@@ -34,15 +34,14 @@
|
||||
[:a.item {:href (bidi/path-for routes/routes :profit-and-loss-detail)
|
||||
:class [(active-when ap = :profit-and-loss-detail)]}
|
||||
|
||||
[:span {:class "icon icon-performance-increase-1" :style {:font-size "25px"}}]
|
||||
[:span {:class "icon icon-performance-graph-calculator" :style {:font-size "25px"}}]
|
||||
[:span {:class "name"} "Profit & Loss Detail"]]]
|
||||
(when (= "admin" (:user/role user))
|
||||
[:li.menu-item
|
||||
[:a.item {:href (bidi/path-for routes/routes :cash-flows)
|
||||
:class [(active-when ap = :cash-flows)]}
|
||||
[:li.menu-item
|
||||
[:a.item {:href (bidi/path-for routes/routes :cash-flows)
|
||||
:class [(active-when ap = :cash-flows)]}
|
||||
|
||||
[:span {:class "icon icon-performance-increase-1" :style {:font-size "25px"}}]
|
||||
[:span {:class "name"} "Cash Flows"]]])
|
||||
[:span {:class "icon icon-money-wallet-open" :style {:font-size "25px"}}]
|
||||
[:span {:class "name"} "Cash Flows"]]]
|
||||
[:li.menu-item
|
||||
[:a.item {:href (bidi/path-for routes/routes :balance-sheet)
|
||||
:class [(active-when ap = :balance-sheet)]}
|
||||
|
||||
Reference in New Issue
Block a user