Able to send email version
This commit is contained in:
@@ -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
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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])}]
|
||||||
|
|||||||
Reference in New Issue
Block a user