Able to send email version

This commit is contained in:
2022-03-23 08:22:57 -07:00
parent 4c0fcf3718
commit 327a5e3856
3 changed files with 74 additions and 42 deletions

View File

@@ -598,13 +598,15 @@
:profit_and_loss {:type :profit_and_loss_report :profit_and_loss {:type :profit_and_loss_report
:args {:client_id {:type :id} :args {:client_id {:type :id}
:client_ids {:type '(list :id)} :client_ids {:type '(list :id)}
:periods {:type '(list :date_range)}} :periods {:type '(list :date_range)}
:include_deltas {:type 'Boolean}}
:resolve :get-profit-and-loss} :resolve :get-profit-and-loss}
:profit_and_loss_pdf {:type :profit_and_loss_pdf :profit_and_loss_pdf {:type :profit_and_loss_pdf
:args {:client_id {:type :id} :args {:client_id {:type :id}
:client_ids {:type '(list :id)} :client_ids {:type '(list :id)}
:periods {:type '(list :date_range)}} :periods {:type '(list :date_range)}
:include_deltas {:type 'Boolean}}
:resolve :profit-and-loss-pdf} :resolve :profit-and-loss-pdf}
:ledger_page {:type :ledger_page :ledger_page {:type :ledger_page

View File

@@ -15,10 +15,6 @@
(java.text DecimalFormat) (java.text DecimalFormat)
(java.util UUID))) (java.util UUID)))
(defn distribute [nums]
(let [sum (reduce + 0 nums)]
(map #(* 100 (/ % sum)) nums)))
(defn date->str [d] (defn date->str [d]
(atime/unparse-local d atime/normal-date)) (atime/unparse-local d atime/normal-date))
@@ -82,7 +78,7 @@
(->> data (->> data
(filter (comp in-range? :numeric-code)) (filter (comp in-range? :numeric-code))
(group-by (juxt :client-id :location)) (group-by (juxt :client-id :location))
(filter (fn [[k as]] (filter (fn [[_ as]]
(not (dollars-0? (reduce + 0 (map :amount as)))))) (not (dollars-0? (reduce + 0 (map :amount as))))))
(mapcat second) (mapcat second)
(map (fn [a] (map (fn [a]
@@ -105,7 +101,7 @@
(defn best-category [a] (defn best-category [a]
(->> ranges (->> ranges
(filter (fn [[category [start end]]] (filter (fn [[_ [start end]]]
(<= start (:numeric-code a) end))) (<= start (:numeric-code a) end)))
first first
first)) first))
@@ -192,7 +188,9 @@
(into [title] (into [title]
(mapcat (mapcat
(fn [v p d] (fn [v p d]
[v p d]) (if (:include-deltas (:args pnl-data))
[v p d]
[v p]))
row row
percent-of-sales percent-of-sales
deltas)) deltas))
@@ -204,27 +202,29 @@
(defn headers [pnl-data header-title] (defn headers [pnl-data header-title]
(let [big-header (into [{:value header-title (let [big-header (into [{:value header-title
:bold true}] :bold true}]
(map-indexed (fn [i p] (map (fn [p]
{:value {:value
(str (date->str (:start p)) (str (date->str (:start p))
" - " " - "
(date->str (:end p))) (date->str (:end p)))
:colspan 3 :colspan (if (-> pnl-data :args :include-deltas)
:align :center 3
:bold true}) 2)
(:periods (:args pnl-data)))) :align :center
:bold true})
(:periods (:args pnl-data))))
sub-header (into [{:value ""}] sub-header (into [{:value ""}]
(mapcat (mapcat
(fn [_] (fn [_]
[{:value "Amount" (cond-> [{:value "Amount"
:align :right :align :right
:bold true} :bold true}
{:value "% Sales" {:value "% Sales"
:align :right :align :right
:bold true} :bold true}]
{:value "Change" (-> pnl-data :args :include-deltas) (conj {:value "Change"
:align :right :align :right
:bold true}]) :bold true})))
(:periods (:args pnl-data))))] (:periods (:args pnl-data))))]
[big-header [big-header
sub-header])) sub-header]))
@@ -442,9 +442,11 @@
(into [new-table] (into [new-table]
(split-table remaining n)))))) (split-table remaining n))))))
(defn break-apart-tables [tables] (defn break-apart-tables [pnl-data tables]
(for [table tables (for [table tables
table (split-table table 10)] table (split-table table (if (:include-deltas (:args pnl-data))
10
9))]
table)) table))
(defn make-pnl [args data] (defn make-pnl [args data]
@@ -462,7 +464,8 @@
(:accounts p2)) (:accounts p2))
) )
(:periods args))) (:periods args)))
report (summarize-pnl (PNLData. (assoc args :deltas true) data (by :db/id clients))) pnl-data (PNLData. args data (by :db/id clients))
report (summarize-pnl pnl-data)
output-stream (ByteArrayOutputStream.)] output-stream (ByteArrayOutputStream.)]
(pdf/pdf (pdf/pdf
(into (into
@@ -470,7 +473,8 @@
:orientation :landscape :orientation :landscape
:font {:size 8}} :font {:size 8}}
[:heading (str "Profit and Loss - " (str/join ", " (map :client/name clients)))]] [:heading (str "Profit and Loss - " (str/join ", " (map :client/name clients)))]]
(for [table (break-apart-tables (concat (:summaries report) (for [table (break-apart-tables pnl-data
(concat (:summaries report)
(:details report)))] (:details report)))]
(table->pdf table))) (table->pdf table)))
output-stream) output-stream)

View File

@@ -169,7 +169,6 @@
(fn [db [_ data]] (fn [db [_ data]]
(-> db (assoc :report (:profit-and-loss data))))) (-> db (assoc :report (:profit-and-loss data)))))
(re-frame/reg-sub (re-frame/reg-sub
::period-inputs ::period-inputs
(fn [db] (fn [db]
@@ -211,13 +210,33 @@
: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)})))
(defn email-body [report-url]
(js/encodeURIComponent
(str
"Your profit and loss report is now ready.
Please download it by clicking this link: " report-url)))
(re-frame/reg-event-fx (re-frame/reg-event-fx
::received-pdf ::received-pdf
(fn [_ [_ result]] [(re-frame/inject-cofx ::inject/sub [::subs/clients-by-id])]
(println result) (fn [{:keys [db ::subs/clients-by-id]} [_ result]]
{:dispatch [::modal/modal-requested {:title "Your report is ready" (let [selected-clients (-> db ::forms/forms ::form :data :clients)
:body [:div single-client? (= (count selected-clients)
[:div "Click " [:a {:href (-> result :profit-and-loss-pdf :report-url) :target "_new"} "here"] " to view it."]]}]})) 1)
client-email (when single-client?
(-> clients-by-id
(get (:id (first selected-clients)))
:email))]
{:dispatch [::modal/modal-requested {:title "Your report is ready"
:body [:div
[:div "Click "
[:a {:href (-> result :profit-and-loss-pdf :report-url) :target "_new"} "here"] " to view it."]
(when single-client?
[:div "Once you've confirmed you're happy with it, click "
[:a {:href (str "mailto:" (or client-email "client@xyz.com") "?body=" (email-body (-> result :profit-and-loss-pdf :report-url)))}
"here"] " to open your email client and to send it to " (str (or client-email "client@xyz.com")) "."])]}]})))
(re-frame/reg-event-fx (re-frame/reg-event-fx
::export-pdf ::export-pdf
[with-user (forms/in-form ::form)] [with-user (forms/in-form ::form)]
@@ -226,6 +245,7 @@
:owns-state {:single ::page} :owns-state {:single ::page}
: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))
:periods (mapv (fn [[start end] ] {:start (date->str start standard) :end (date->str end standard)} ) :periods (mapv (fn [[start end] ] {:start (date->str start standard) :end (date->str end standard)} )
(:periods (:data db)))} (:periods (:data db)))}
[:report_url]]]} [:report_url]]]}
@@ -239,7 +259,7 @@
(re-frame/reg-event-db (re-frame/reg-event-db
::change ::change-internal
(forms/change-handler ::form (forms/change-handler ::form
(fn [data field value] (fn [data field value]
(cond (cond
@@ -260,6 +280,13 @@
:else nil) :else nil)
))) )))
(re-frame/reg-event-fx
::change
[with-user (forms/in-form ::form)]
(fn [{:keys [db]} [_ & event]]
{:db (dissoc db :report)
:dispatch (into [::change-internal] event)}))
(defn data-params->query-params [params client-id] (defn data-params->query-params [params client-id]
(when params (when params
@@ -956,8 +983,7 @@
(re-frame/reg-event-fx (re-frame/reg-event-fx
::unmounted-pnl ::unmounted-pnl
(fn [{:keys [db]} _] (fn [{:keys [db]} _]
{:dispatch [::data-page/dispose ::ledger] {::track/dispose {:id ::ledger-params}}))
::track/dispose {:id ::ledger-params}}))
(re-frame/reg-event-fx (re-frame/reg-event-fx
::mounted-pnl ::mounted-pnl
@@ -974,9 +1000,9 @@
: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})
::track/register {:id ::ledger-params ::track/register {:id ::ledger-params
:subscription [::data-page/params ::ledger] :subscription [::data-page/params ::ledger]
:event-fn (fn [params] [::ledger-params-change params])}}))) :event-fn (fn [params] [::ledger-params-change params])}})))
(defn ledger-list [_ ] (defn ledger-list [_ ]
[:div [:a.delete.is-pulled-right {:on-click (dispatch-event [::ledger-list-closing])}] [:div [:a.delete.is-pulled-right {:on-click (dispatch-event [::ledger-list-closing])}]