diff --git a/.gitignore b/.gitignore index a77ae86f..6e4583db 100644 --- a/.gitignore +++ b/.gitignore @@ -29,3 +29,4 @@ backups terraform/.gitx .cpcache .datomic-ions +.cpcache diff --git a/src/clj/auto_ap/graphql/ledger.clj b/src/clj/auto_ap/graphql/ledger.clj index 9cfacb58..3df91768 100644 --- a/src/clj/auto_ap/graphql/ledger.clj +++ b/src/clj/auto_ap/graphql/ledger.clj @@ -15,10 +15,9 @@ [auto-ap.ledger :refer [build-account-lookup]] [auto-ap.ledger.reports :as l-reports] [auto-ap.parse.util :as parse] - [auto-ap.pdf.ledger - :refer [print-balance-sheet print-journal-detail-report print-pnl]] [auto-ap.time :as atime] [auto-ap.utils :refer [by dollars=]] + [auto-ap.pdf.ledger :refer [print-balance-sheet print-pnl print-journal-detail-report print-cash-flows]] [clj-time.coerce :as coerce] [clj-time.core :as t] [clojure.data.csv :as csv] @@ -275,6 +274,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)] @@ -750,6 +754,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} @@ -830,6 +842,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 diff --git a/src/clj/auto_ap/pdf/ledger.clj b/src/clj/auto_ap/pdf/ledger.clj index 469039aa..9391abea 100644 --- a/src/clj/auto_ap/pdf/ledger.clj +++ b/src/clj/auto_ap/pdf/ledger.clj @@ -180,7 +180,6 @@ (.toByteArray output-stream))) (defn make-pnl [args data] - (let [data (<-graphql data) args (<-graphql args) clients (pull-many (dc/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 (pull-many (dc/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) diff --git a/src/cljs/auto_ap/views/pages/ledger/cash_flows.cljs b/src/cljs/auto_ap/views/pages/ledger/cash_flows.cljs index 5102cc1a..5d91d731 100644 --- a/src/cljs/auto_ap/views/pages/ledger/cash_flows.cljs +++ b/src/cljs/auto_ap/views/pages/ledger/cash_flows.cljs @@ -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]]}] diff --git a/src/cljs/auto_ap/views/pages/ledger/side_bar.cljs b/src/cljs/auto_ap/views/pages/ledger/side_bar.cljs index 145b72ad..330d9f00 100644 --- a/src/cljs/auto_ap/views/pages/ledger/side_bar.cljs +++ b/src/cljs/auto_ap/views/pages/ledger/side_bar.cljs @@ -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)]}