profit and loss changes for more than one client.
This commit is contained in:
@@ -13,6 +13,8 @@
|
||||
[:span.icon [:i.fa {:class icon}]]]
|
||||
(r/children (r/current-component)))])
|
||||
|
||||
|
||||
|
||||
(defn sl-icon [{:keys [event icon class on-click] :as params}]
|
||||
[:a.button (cond-> params
|
||||
true (dissoc :event :icon)
|
||||
@@ -25,3 +27,14 @@
|
||||
:on-click (dispatch-event event)}
|
||||
[:span.icon [:i.fa.fa-plus]]
|
||||
[:span name]])
|
||||
|
||||
(defn dropdown [{:keys [event icon class on-click] :as params}]
|
||||
[:a.button (cond-> params
|
||||
true (dissoc :event :icon)
|
||||
(and (not on-click)
|
||||
event)
|
||||
(assoc :on-click (dispatch-event event)))
|
||||
(conj (into
|
||||
[:<>]
|
||||
(r/children (r/current-component)))
|
||||
[:span.icon [:i.fa.fa-chevron-down]])])
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
(ns auto-ap.views.components.switch-field)
|
||||
|
||||
(defn switch-field [{:keys [id label on-change checked]}]
|
||||
(defn switch-field [{:keys [id label on-change checked class]}]
|
||||
[:<>
|
||||
[:input.switch {:type "checkbox" :id id :on-change on-change :checked checked}]
|
||||
[:input.switch {:type "checkbox" :id id :on-change on-change :checked checked :class class}]
|
||||
[:label {:for id} label]])
|
||||
|
||||
@@ -8,10 +8,13 @@
|
||||
[auto-ap.forms :as forms]
|
||||
[auto-ap.views.pages.ledger.side-bar :refer [ledger-side-bar]]
|
||||
[auto-ap.views.components.typeahead :refer [typeahead-v3]]
|
||||
[auto-ap.views.components.buttons :as buttons]
|
||||
[auto-ap.views.components.switch-field :refer [switch-field]]
|
||||
[auto-ap.views.components.modal :as modal]
|
||||
[auto-ap.views.utils :refer [date->str date-picker date-picker-friendly bind-field standard pretty dispatch-event local-today ->% ->$ str->date with-user dispatch-value-change query-params]]
|
||||
[cljs-time.core :as t]
|
||||
[re-frame.core :as re-frame]
|
||||
[react-dom :as react-dom]
|
||||
[auto-ap.status :as status]
|
||||
[auto-ap.views.pages.data-page :as data-page]
|
||||
[vimsical.re-frame.fx.track :as track]
|
||||
@@ -139,10 +142,6 @@
|
||||
(fn [db [_ data]]
|
||||
(-> db (assoc :report (:profit-and-loss data)))))
|
||||
|
||||
(re-frame/reg-sub
|
||||
::params
|
||||
(fn [db]
|
||||
(-> db ::params)))
|
||||
|
||||
(re-frame/reg-sub
|
||||
::period-inputs
|
||||
@@ -152,7 +151,12 @@
|
||||
(re-frame/reg-sub
|
||||
::periods
|
||||
(fn [db]
|
||||
(::periods db)))
|
||||
(-> db ::forms/forms ::form :data :periods)))
|
||||
|
||||
(re-frame/reg-sub
|
||||
::include-deltas
|
||||
(fn [db]
|
||||
(-> db ::forms/forms ::form :data :include-deltas)))
|
||||
|
||||
;; EVENTS
|
||||
|
||||
@@ -165,24 +169,22 @@
|
||||
::params-change
|
||||
[with-user (forms/in-form ::form)]
|
||||
(fn [{:keys [db user] :as cofx}]
|
||||
(let [c @(re-frame/subscribe [::subs/client])]
|
||||
(cond-> {:graphql {:token user
|
||||
:owns-state {:single ::page}
|
||||
:query-obj {:venia/queries [[:profit-and-loss
|
||||
{:client-ids (or (some-> (:id c) vector)
|
||||
(some-> (:id (:client (:data db)))
|
||||
vector))
|
||||
:periods (mapv (fn [[start end] ] {:start (date->str start standard) :end (date->str end standard)} )
|
||||
(:periods (:data db)))}
|
||||
[[:periods [[:accounts [:name :amount :client_id :account-type :id :count :numeric-code :location]]]]]]]}
|
||||
:on-success [::received]}
|
||||
:set-uri-params {:periods (mapv (fn [[start end title]]
|
||||
[(date->str start standard)
|
||||
(date->str end standard)])
|
||||
(:periods (:data db)))
|
||||
:client (select-keys (:client (:data db))
|
||||
[:name :id])}
|
||||
:db (dissoc db :report)}))))
|
||||
(cond-> {:graphql {:token user
|
||||
:owns-state {:single ::page}
|
||||
:query-obj {:venia/queries [[:profit-and-loss
|
||||
{:client-ids (some-> (:id (:client (:data db)))
|
||||
vector)
|
||||
:periods (mapv (fn [[start end] ] {:start (date->str start standard) :end (date->str end standard)} )
|
||||
(:periods (:data db)))}
|
||||
[[:periods [[:accounts [:name :amount :client_id :account-type :id :count :numeric-code :location]]]]]]]}
|
||||
:on-success [::received]}
|
||||
:set-uri-params {:periods (mapv (fn [[start end title]]
|
||||
[(date->str start standard)
|
||||
(date->str end standard)])
|
||||
(:periods (:data db)))
|
||||
:client (select-keys (:client (:data db))
|
||||
[:name :id])}
|
||||
:db (dissoc db :report)})))
|
||||
|
||||
|
||||
|
||||
@@ -276,7 +278,6 @@
|
||||
:can-submit [::can-submit-period-form]
|
||||
:id ::period-form}))
|
||||
|
||||
;; 877 w fremont ave suite i4
|
||||
(defn change-period-body [idx which]
|
||||
(let [{:keys [data active? error id]} @(re-frame/subscribe [::forms/form ::period-form])
|
||||
{:keys [form-inline horizontal-field field raw-field error-notification submit-button]} change-period-form]
|
||||
@@ -424,11 +425,12 @@
|
||||
{:key (str "between-" i)}))]))
|
||||
|
||||
|
||||
;; reimplement include-deltas. Are numbers even correct? support actually using more than 1 client.
|
||||
;; TODO Allow choosing more than one client
|
||||
;; TODO allow "sandwhiching" clients data
|
||||
;; TODO do we need squashing locations?
|
||||
|
||||
(defn grouping [{:keys [header type groupings location periods all-accounts]}]
|
||||
|
||||
(let [params @(re-frame/subscribe [::params])]
|
||||
(let [include-deltas @(re-frame/subscribe [::include-deltas])]
|
||||
[:<>
|
||||
(doall
|
||||
(for [[grouping-name from to] groupings
|
||||
@@ -445,7 +447,7 @@
|
||||
(fn [i]
|
||||
[:td])
|
||||
periods
|
||||
(:include-deltas params))]
|
||||
include-deltas)]
|
||||
[:<>
|
||||
(for [{:keys [numeric-code name]} account-codes]
|
||||
^{:key numeric-code}
|
||||
@@ -462,7 +464,7 @@
|
||||
[:td.has-text-right (->$ (- (get-in all-accounts [i [numeric-code location] :amount] 0.0)
|
||||
(get-in all-accounts [(dec i) [numeric-code location] :amount] 0.0)))])
|
||||
periods
|
||||
(:include-deltas params))])]
|
||||
include-deltas)])]
|
||||
|
||||
[:tr
|
||||
[:th]
|
||||
@@ -477,7 +479,7 @@
|
||||
[:th.has-text-right.total (->$ (- (aggregate-accounts (filter-accounts all-accounts i [from to] location))
|
||||
(aggregate-accounts (filter-accounts all-accounts (dec i) [from to] location))))])
|
||||
periods
|
||||
(:include-deltas params))]]))]))
|
||||
include-deltas)]]))]))
|
||||
|
||||
|
||||
|
||||
@@ -485,7 +487,7 @@
|
||||
(let [all-accounts @(re-frame/subscribe [::all-accounts])
|
||||
periods @(re-frame/subscribe [::periods])
|
||||
[min-numeric-code max-numeric-code] (ranges type)
|
||||
params @(re-frame/subscribe [::params])]
|
||||
include-deltas @(re-frame/subscribe [::include-deltas])]
|
||||
|
||||
[:<>
|
||||
[:tr [:th.is-size-5 title]]
|
||||
@@ -509,12 +511,12 @@
|
||||
[:th.has-text-right (->$ (- (aggregate-accounts (filter-accounts all-accounts i [min-numeric-code max-numeric-code] location))
|
||||
(aggregate-accounts (filter-accounts all-accounts (dec i) [min-numeric-code max-numeric-code] location))))])
|
||||
periods
|
||||
(:include-deltas params))]]))
|
||||
include-deltas)]]))
|
||||
|
||||
(defn subtotal [types negs title location]
|
||||
(let [all-accounts @(re-frame/subscribe [::all-accounts])
|
||||
periods @(re-frame/subscribe [::periods])
|
||||
params @(re-frame/subscribe [::params])]
|
||||
include-deltas @(re-frame/subscribe [::include-deltas])]
|
||||
[:tr [:th.is-size-5 title]
|
||||
|
||||
(map-periods
|
||||
@@ -536,7 +538,7 @@
|
||||
(negs t) (map #(update % :amount -))))
|
||||
types))))])
|
||||
periods
|
||||
(:include-deltas params))]))
|
||||
include-deltas)]))
|
||||
|
||||
(defn period-header [{:keys [include-deltas periods]}]
|
||||
[:<>
|
||||
@@ -582,13 +584,13 @@
|
||||
[subtotal [:sales :cogs :payroll :controllable :fixed-overhead :ownership-controllable] #{:cogs :payroll :controllable :fixed-overhead :ownership-controllable} (str location " Net Income") location]
|
||||
[subtotal [:sales :cogs :payroll :controllable :fixed-overhead :ownership-controllable] #{:cogs :payroll :controllable :fixed-overhead :ownership-controllable} "Net Income" nil]])
|
||||
|
||||
(defn location-summary [location params]
|
||||
(defn location-summary [location include-deltas]
|
||||
(let [periods @(re-frame/subscribe [::periods])]
|
||||
[:div
|
||||
[:h2.title.is-4.mb-4 location " Summary"]
|
||||
[:table.table.compact.balance-sheet.mb-6
|
||||
[:tbody
|
||||
[period-header {:include-deltas (:include-deltas params)
|
||||
[period-header {:include-deltas include-deltas
|
||||
:periods periods}]
|
||||
|
||||
|
||||
@@ -597,9 +599,7 @@
|
||||
[subtotal [:payroll ]#{} "Payroll" location]
|
||||
[subtotal [:sales :payroll :cogs] #{:payroll :cogs} "Gross Profits" location]
|
||||
[subtotal [:controllable :fixed-overhead :ownership-controllable] #{} "Overhead" location]
|
||||
[subtotal [:sales :cogs :payroll :controllable :fixed-overhead :ownership-controllable] #{:cogs :payroll :controllable :fixed-overhead :ownership-controllable} "Net Income" location]]]
|
||||
|
||||
]))
|
||||
[subtotal [:sales :cogs :payroll :controllable :fixed-overhead :ownership-controllable] #{:cogs :payroll :controllable :fixed-overhead :ownership-controllable} "Net Income" location]]]]))
|
||||
|
||||
(re-frame/reg-sub
|
||||
::can-submit
|
||||
@@ -611,213 +611,265 @@
|
||||
:submit-event [::params-change]
|
||||
:id ::form}))
|
||||
|
||||
(defn report-control-detail [{:keys [active box which]} children]
|
||||
(when (and @box
|
||||
(= which @active))
|
||||
(react-dom/createPortal (reagent/as-element
|
||||
[:div.notification.is-light
|
||||
[:a.delete {:on-click (fn [] (reset! active nil))}]
|
||||
children
|
||||
])
|
||||
@box)))
|
||||
|
||||
(defn report-controls [pnl-form]
|
||||
(let [!box (reagent/atom nil)
|
||||
active (reagent/atom nil)]
|
||||
(fn [pnl-form]
|
||||
(let [{:keys [form-inline field raw-field error-notification submit-button ]} pnl-form
|
||||
{:keys [data report active? error id]} @(re-frame/subscribe [::forms/form ::form])
|
||||
{:keys [periods selected-period include-deltas]} data]
|
||||
[:div.report-controls
|
||||
[:div.level.mb-2
|
||||
[:div.level-left
|
||||
[:div.level-item
|
||||
[buttons/dropdown {:on-click (fn [] (reset! active :clients))}
|
||||
[:span (str "Companies"
|
||||
(when (:client data)
|
||||
(str " (" (:name (:client data)) ")")))]]
|
||||
[report-control-detail {:active active :box !box :which :clients}
|
||||
[:div {:style {:width "20em"}}
|
||||
[:h4.subtitle "Companies"]
|
||||
(raw-field
|
||||
[typeahead-v3 {:entities @(re-frame/subscribe [::subs/clients])
|
||||
:entity->text :name
|
||||
:type "typeahead-v3"
|
||||
:field [:client]}])]]]
|
||||
[:div.level-item
|
||||
[buttons/dropdown {:on-click (fn [] (reset! active :range))}
|
||||
[:span (str "Range"
|
||||
(when selected-period
|
||||
(str " (" selected-period ")")))]]
|
||||
[report-control-detail {:active active :box !box :which :range}
|
||||
[:div
|
||||
[:h4.subtitle "Range"]
|
||||
[:div.field.is-grouped
|
||||
[:div.control
|
||||
[:div.field.has-addons
|
||||
[:div.control
|
||||
(raw-field
|
||||
[date-picker-friendly {:placeholder "End date"
|
||||
:type "date"
|
||||
:field [:thirteen-periods-end]}])]
|
||||
[:div.control
|
||||
[:a.button
|
||||
{:class (when (= selected-period "13 periods") "is-active")
|
||||
:on-click (dispatch-event
|
||||
[::forms/change ::form
|
||||
[:periods]
|
||||
(let [today (or (some-> (:thirteen-periods-end data) (str->date standard))
|
||||
(local-today))]
|
||||
(into
|
||||
[[(t/plus (t/minus today (t/weeks (* 13 4)))
|
||||
(t/days 1))
|
||||
today
|
||||
"Total"]]
|
||||
(for [i (range 13)]
|
||||
[(t/plus (t/minus today (t/weeks (* (inc i) 4)))
|
||||
(t/days 1))
|
||||
(t/minus today (t/weeks (* i 4)))])))
|
||||
[:selected-period] "13 periods"])}
|
||||
"13 periods"]]]]
|
||||
|
||||
[:div.control
|
||||
[:div.field.has-addons
|
||||
[:div.control
|
||||
(raw-field
|
||||
[date-picker-friendly {:placeholder "End date"
|
||||
:type "date"
|
||||
:field [:twelve-periods-end]}])
|
||||
]
|
||||
[:div.control
|
||||
[:a.button
|
||||
{:class (when (= selected-period "12 months") "is-active")
|
||||
:on-click (dispatch-event
|
||||
[::forms/change ::form
|
||||
[:periods]
|
||||
(let [end-date (or (some-> (:twelve-periods-end data) (str->date standard))
|
||||
(local-today))
|
||||
this-month (t/local-date (t/year end-date)
|
||||
(t/month end-date)
|
||||
1)
|
||||
]
|
||||
(into
|
||||
[[(t/minus this-month (t/months 11))
|
||||
(t/minus (t/plus this-month (t/months 1))
|
||||
(t/days 1))
|
||||
"Total"]]
|
||||
(for [i (range 12)]
|
||||
[(t/minus this-month (t/months (- 11 i)))
|
||||
(t/minus (t/minus this-month (t/months (- 10 i)))
|
||||
(t/days 1))])))
|
||||
[:selected-period] "12 months"])}
|
||||
"12 months"]]]]
|
||||
|
||||
[:div.control
|
||||
[:a.button
|
||||
{:class (when (= selected-period "Last week") "is-active")
|
||||
:on-click (dispatch-event
|
||||
[::forms/change ::form
|
||||
[:periods]
|
||||
(let [last-sunday (loop [current (local-today)]
|
||||
(if (= 7 (t/day-of-week current))
|
||||
current
|
||||
(recur (t/minus current (t/period :days 1)))))]
|
||||
|
||||
(and-last-year [(t/minus last-sunday (t/period :days 6)) last-sunday]))
|
||||
[:selected-period] "Last week"])}
|
||||
"Last week"]]
|
||||
[:div.control
|
||||
[:a.button
|
||||
{:class (when (= selected-period "Week to date") "is-active")
|
||||
:on-click (dispatch-event
|
||||
[::forms/change ::form
|
||||
[:periods]
|
||||
(and-last-year [(loop [current (local-today)]
|
||||
(if (= 1 (t/day-of-week current))
|
||||
current
|
||||
(recur (t/minus current (t/period :days 1)))))
|
||||
(local-today)])
|
||||
[:selected-period] "Week to date"])}
|
||||
"Week to date"]]
|
||||
[:div.control
|
||||
[:a.button
|
||||
{:class (when (= selected-period "Last Month") "is-active")
|
||||
:on-click (dispatch-event
|
||||
|
||||
[::forms/change ::form
|
||||
[:periods]
|
||||
(and-last-year [(t/minus (t/local-date (t/year (local-today))
|
||||
(t/month (local-today))
|
||||
1)
|
||||
(t/period :months 1))
|
||||
(t/minus (t/local-date (t/year (local-today))
|
||||
(t/month (local-today))
|
||||
1)
|
||||
(t/period :days 1))])
|
||||
[:selected-period] "Last Month"])}
|
||||
"Last Month"]]
|
||||
[:div.control
|
||||
[:a.button
|
||||
{:class (when (= selected-period "Month to date") "is-active")
|
||||
:on-click (dispatch-event
|
||||
[::forms/change ::form
|
||||
[:periods]
|
||||
(and-last-year [(t/local-date (t/year (local-today))
|
||||
(t/month (local-today))
|
||||
1)
|
||||
(local-today)])
|
||||
[:selected-period] "Month to date"]
|
||||
)}
|
||||
"Month to date"]]
|
||||
[:div.control
|
||||
[:a.button
|
||||
{:class (when (= selected-period "Year to date") "is-active")
|
||||
:on-click (dispatch-event
|
||||
[::forms/change ::form
|
||||
[:periods]
|
||||
(and-last-year [(t/local-date (t/year (local-today)) 1 1)
|
||||
(local-today)])
|
||||
[:selected-period] "Year to date"])}
|
||||
"Year to date"]]
|
||||
[:div.control
|
||||
[:a.button
|
||||
{:class (when (= selected-period "Full year") "is-active")
|
||||
:on-click (dispatch-event
|
||||
[::forms/change ::form
|
||||
[:periods]
|
||||
(and-last-year [(t/plus (t/minus (local-today) (t/period :years 1))
|
||||
(t/period :days 1))
|
||||
(local-today)])
|
||||
[:selected-period] "Full year"])}
|
||||
"Full year"]]]
|
||||
[:div
|
||||
[:div.field
|
||||
[:label.checkbox
|
||||
(raw-field
|
||||
[:input {:type "checkbox"
|
||||
:field [:show-advanced?]}])
|
||||
" Show Advanced"]]]
|
||||
(when (:show-advanced? data)
|
||||
(doall
|
||||
(for [[_ i] (map vector periods (range))]
|
||||
^{:key i}
|
||||
[:div.field.is-grouped
|
||||
[:div.control
|
||||
[:p.help "From"]
|
||||
(raw-field
|
||||
[date-picker-friendly {:type "date"
|
||||
:field [:periods i 0]}])]
|
||||
|
||||
[:div.control
|
||||
[:p.help "To"]
|
||||
(raw-field
|
||||
[date-picker-friendly {:type "date"
|
||||
:field [:periods i 1]}])]])))]]]
|
||||
|
||||
[:div.level-item
|
||||
[:div
|
||||
[switch-field {:id "include-deltas"
|
||||
:checked (boolean include-deltas)
|
||||
:on-change (fn [e]
|
||||
(re-frame/dispatch [::forms/change ::form
|
||||
[:include-deltas] (.-checked (.-target e))]))
|
||||
:label "Include deltas"
|
||||
:type "checkbox"}]]]]
|
||||
[:div.level-right
|
||||
[:button.button.is-primary "Run"]]]
|
||||
[:div.report-control-detail {:ref (fn [el]
|
||||
(when-not @!box
|
||||
(reset! !box el)))}]]))))
|
||||
|
||||
(defn profit-and-loss-content []
|
||||
(let [current-client @(re-frame/subscribe [::subs/client])
|
||||
clients @(re-frame/subscribe [::subs/clients])
|
||||
user @(re-frame/subscribe [::subs/user])
|
||||
(let [user @(re-frame/subscribe [::subs/user])
|
||||
status @(re-frame/subscribe [::status/single ::page])
|
||||
params @(re-frame/subscribe [::params])
|
||||
unresolved-accounts @(re-frame/subscribe [::uncategorized-accounts])
|
||||
{:keys [data report active? error id]} @(re-frame/subscribe [::forms/form ::form])
|
||||
{:keys [form-inline field raw-field error-notification submit-button ]} pnl-form
|
||||
periods (:periods data)]
|
||||
(when data
|
||||
(form-inline {}
|
||||
[:div
|
||||
[:h1.title "Profit and Loss - " (:name current-client)]
|
||||
[status/status-notification {:statuses [[::status/single ::page]]}]
|
||||
[:div.report-controls
|
||||
(when-not current-client
|
||||
[:<>
|
||||
[:h2.title.is-4 "Entities"]
|
||||
(raw-field
|
||||
[typeahead-v3 {:entities @(re-frame/subscribe [::subs/clients])
|
||||
:entity->text :name
|
||||
:type "typeahead-v3"
|
||||
:field [:client]}])])
|
||||
[:h2.title.is-4 "Range"]
|
||||
[:div
|
||||
[:div.field.is-grouped
|
||||
[:div.control
|
||||
[:div.field.has-addons
|
||||
[:div.control
|
||||
(raw-field
|
||||
[date-picker-friendly {:placeholder "End date"
|
||||
:type "date"
|
||||
:field [:thirteen-periods-end]}])]
|
||||
[:div.control
|
||||
[:a.button
|
||||
{:class (when (= (:selected params) "13 periods") "is-active")
|
||||
:on-click (dispatch-event
|
||||
[::forms/change ::form
|
||||
[:periods]
|
||||
(let [today (or (some-> (:thirteen-periods-end data) (str->date standard))
|
||||
(local-today))]
|
||||
(into
|
||||
[[(t/plus (t/minus today (t/weeks (* 13 4)))
|
||||
(t/days 1))
|
||||
today
|
||||
"Total"]]
|
||||
(for [i (range 13)]
|
||||
[(t/plus (t/minus today (t/weeks (* (inc i) 4)))
|
||||
(t/days 1))
|
||||
(t/minus today (t/weeks (* i 4)))])))])}
|
||||
"13 periods"]]]]
|
||||
(form-inline {}
|
||||
[:div
|
||||
[status/status-notification {:statuses [[::status/single ::page]]}]
|
||||
[report-controls pnl-form]
|
||||
|
||||
[status/big-loader status]
|
||||
(when (and (not= :loading (:state status))
|
||||
report)
|
||||
|
||||
[:div.control
|
||||
[:div.field.has-addons
|
||||
[:div.control
|
||||
(raw-field
|
||||
[date-picker-friendly {:placeholder "End date"
|
||||
:type "date"
|
||||
:field [:twelve-periods-end]}])
|
||||
]
|
||||
[:div.control
|
||||
[:a.button
|
||||
{:class (when (= (:selected params) "13 periods") "is-active")
|
||||
:on-click (dispatch-event
|
||||
[::forms/change ::form
|
||||
[:periods]
|
||||
(let [end-date (or (some-> (:twelve-periods-end data) (str->date standard))
|
||||
(local-today))
|
||||
this-month (t/local-date (t/year end-date)
|
||||
(t/month end-date)
|
||||
1)
|
||||
]
|
||||
(into
|
||||
[[(t/minus this-month (t/months 11))
|
||||
(t/minus (t/plus this-month (t/months 1))
|
||||
(t/days 1))
|
||||
"Total"]]
|
||||
(for [i (range 12)]
|
||||
[(t/minus this-month (t/months (- 11 i)))
|
||||
(t/minus (t/minus this-month (t/months (- 10 i)))
|
||||
(t/days 1))])))])}
|
||||
"12 months"]]]]
|
||||
[:div
|
||||
|
||||
[:div.control
|
||||
[:a.button
|
||||
{:class (when (= (:selected params) "Last week") "is-active")
|
||||
:on-click (dispatch-event
|
||||
[::forms/change ::form
|
||||
[:periods]
|
||||
(let [last-sunday (loop [current (local-today)]
|
||||
(if (= 7 (t/day-of-week current))
|
||||
current
|
||||
(recur (t/minus current (t/period :days 1)))))]
|
||||
|
||||
(and-last-year [(t/minus last-sunday (t/period :days 6)) last-sunday]))])}
|
||||
"Last week"]]
|
||||
[:div.control
|
||||
[:a.button
|
||||
{:class (when (= (:selected params) "Week to date") "is-active")
|
||||
:on-click (dispatch-event
|
||||
[::forms/change ::form
|
||||
[:periods]
|
||||
(and-last-year [(loop [current (local-today)]
|
||||
(if (= 1 (t/day-of-week current))
|
||||
current
|
||||
(recur (t/minus current (t/period :days 1)))))
|
||||
(local-today)])])}
|
||||
"Week to date"]]
|
||||
[:div.control
|
||||
[:a.button
|
||||
{:class (when (= (:selected params) "Last Month") "is-active")
|
||||
:on-click (dispatch-event
|
||||
|
||||
[::forms/change ::form
|
||||
[:periods]
|
||||
(and-last-year [(t/minus (t/local-date (t/year (local-today))
|
||||
(t/month (local-today))
|
||||
1)
|
||||
(t/period :months 1))
|
||||
(t/minus (t/local-date (t/year (local-today))
|
||||
(t/month (local-today))
|
||||
1)
|
||||
(t/period :days 1))])])}
|
||||
"Last Month"]]
|
||||
[:div.control
|
||||
[:a.button
|
||||
{:class (when (= (:selected params) "Month to date") "is-active")
|
||||
:on-click (dispatch-event
|
||||
[::forms/change ::form
|
||||
[:periods]
|
||||
(and-last-year [(t/local-date (t/year (local-today))
|
||||
(t/month (local-today))
|
||||
1)
|
||||
(local-today)])]
|
||||
)}
|
||||
"Month to date"]]
|
||||
[:div.control
|
||||
[:a.button
|
||||
{:class (when (= (:selected params) "Year to date") "is-active")
|
||||
:on-click (dispatch-event
|
||||
[::forms/change ::form
|
||||
[:periods]
|
||||
(and-last-year [(t/local-date (t/year (local-today)) 1 1)
|
||||
(local-today)])])}
|
||||
"Year to date"]]
|
||||
[:div.control
|
||||
[:a.button
|
||||
{:class (when (= (:selected params) "Full year") "is-active")
|
||||
:on-click (dispatch-event
|
||||
[::forms/change ::form
|
||||
[:periods]
|
||||
(and-last-year [(t/plus (t/minus (local-today) (t/period :years 1))
|
||||
(t/period :days 1))
|
||||
(local-today)])])}
|
||||
"Full year"]]]]
|
||||
[:div
|
||||
[:div.field
|
||||
[:label.checkbox
|
||||
(raw-field
|
||||
[:input {:type "checkbox"
|
||||
:field [:show-advanced?]}])
|
||||
" Show Advanced"]]]
|
||||
(when (:show-advanced? data)
|
||||
(doall
|
||||
(for [[_ i] (map vector periods (range))]
|
||||
^{:key i}
|
||||
[:div.field.is-grouped
|
||||
[:div.control
|
||||
[:p.help "From"]
|
||||
(raw-field
|
||||
[date-picker-friendly {:type "date"
|
||||
:field [:periods i 0]}])]
|
||||
|
||||
[:div.control
|
||||
[:p.help "To"]
|
||||
(raw-field
|
||||
[date-picker-friendly {:type "date"
|
||||
:field [:periods i 1]}])]])))
|
||||
(submit-button "Run")]
|
||||
[status/big-loader status]
|
||||
(when (and (not= :loading (:state status))
|
||||
report)
|
||||
|
||||
[:div
|
||||
(when (seq unresolved-accounts)
|
||||
[:div.notification.is-warning.is-light
|
||||
"This report does not include " (str/join ", "
|
||||
(map #(str (:count %) " unresolved ledger entries for " (if (str/blank? (:location %))
|
||||
" all locations"
|
||||
(:location %)))
|
||||
unresolved-accounts))])
|
||||
[:h1.title "Profit and Loss - " (:name (:client data))]
|
||||
(when (seq unresolved-accounts)
|
||||
[:div.notification.is-warning.is-light
|
||||
"This report does not include " (str/join ", "
|
||||
(map #(str (:count %) " unresolved ledger entries for " (if (str/blank? (:location %))
|
||||
" all locations"
|
||||
(:location %)))
|
||||
unresolved-accounts))])
|
||||
[:<>
|
||||
(for [location @(re-frame/subscribe [::locations])]
|
||||
^{:key (str location "-summary")}
|
||||
[location-summary location (:include-deltas data)]
|
||||
)]
|
||||
[:h2.title.is-4 {:style {:margin-bottom "1rem"}} "Detail"]
|
||||
[:table.table.compact.balance-sheet
|
||||
[:tbody
|
||||
[period-header {:include-deltas (:include-deltas data)
|
||||
:periods periods}]
|
||||
|
||||
[:<>
|
||||
(for [location @(re-frame/subscribe [::locations])]
|
||||
^{:key (str location "-summary")}
|
||||
[location-summary location params]
|
||||
)]
|
||||
[:h2.title.is-4 {:style {:margin-bottom "1rem"}} "Detail"]
|
||||
[:table.table.compact.balance-sheet
|
||||
[:tbody
|
||||
[period-header {:include-deltas (:include-deltas params)
|
||||
:periods periods}]
|
||||
|
||||
[:<>
|
||||
(for [location @(re-frame/subscribe [::locations])]
|
||||
^{:key location}
|
||||
[location-rows location])]]]])]))))
|
||||
^{:key location}
|
||||
[location-rows location])]]]])])))
|
||||
|
||||
(re-frame/reg-event-fx
|
||||
::unmounted-pnl
|
||||
@@ -836,7 +888,8 @@
|
||||
(fn [dt]
|
||||
(str->date dt standard))
|
||||
period))))
|
||||
:client (:client qp)
|
||||
:client (or (:client qp)
|
||||
(some-> @(re-frame/subscribe [::subs/client]) (select-keys [:name :id])))
|
||||
:include-deltas true})
|
||||
::track/register {:id ::ledger-params
|
||||
:subscription [::data-page/params ::ledger]
|
||||
|
||||
Reference in New Issue
Block a user