259 lines
11 KiB
Clojure
259 lines
11 KiB
Clojure
(ns auto-ap.views.pages.ledger.balance-sheet
|
|
(:require
|
|
[auto-ap.forms :as forms]
|
|
[auto-ap.ledger.reports :as l-reports]
|
|
[auto-ap.status :as status]
|
|
[auto-ap.subs :as subs]
|
|
[auto-ap.views.components.layouts
|
|
:refer [appearing-side-bar side-bar-layout]]
|
|
[auto-ap.views.components.switch-field :refer [switch-field]]
|
|
[auto-ap.views.pages.data-page :as data-page]
|
|
[auto-ap.views.pages.ledger.side-bar :refer [ledger-side-bar]]
|
|
[auto-ap.views.pages.ledger.table :as ledger-table]
|
|
[auto-ap.views.utils
|
|
:refer [date->str
|
|
date-picker-friendly
|
|
dispatch-event
|
|
local-now
|
|
standard
|
|
with-user]]
|
|
[cljs-time.core :as t]
|
|
[clojure.set :as set]
|
|
[re-frame.core :as re-frame]
|
|
[reagent.core :as reagent]
|
|
[vimsical.re-frame.fx.track :as track]
|
|
[auto-ap.views.pages.ledger.report-table :as rtable]))
|
|
|
|
(defn data-params->query-params [params]
|
|
(when params
|
|
{:start (:start params 0)
|
|
:sort (:sort params)
|
|
:per-page (:per-page params)
|
|
:vendor-id (:id (:vendor params))
|
|
:client-id (:client-id params )
|
|
:from-numeric-code (:from-numeric-code params)
|
|
:to-numeric-code (:to-numeric-code params)
|
|
:date-range (:date-range params)}))
|
|
|
|
(re-frame/reg-sub
|
|
::can-submit
|
|
(fn [_]
|
|
true))
|
|
|
|
|
|
(re-frame/reg-sub
|
|
::ledger-list-active?
|
|
(fn [db]
|
|
(-> db ::ledger-list-active?)))
|
|
|
|
(re-frame/reg-event-db
|
|
::received
|
|
[(forms/in-form ::form)]
|
|
(fn [db [_ data]]
|
|
(-> db
|
|
(assoc :report (:balance-sheet data)))))
|
|
|
|
(re-frame/reg-event-fx
|
|
::change
|
|
[with-user (forms/in-form ::form)]
|
|
(fn [{:keys [db]} [_ & event]]
|
|
{:db (dissoc db :report)
|
|
:dispatch-n [(into [::forms/change ::form] event)
|
|
[::ledger-list-closing]]}))
|
|
|
|
(re-frame/reg-event-db
|
|
::ledger-list-closing
|
|
(fn [db]
|
|
(assoc db ::ledger-list-active? false)))
|
|
|
|
|
|
(re-frame/reg-event-fx
|
|
::report-requested
|
|
[with-user (forms/in-form ::form)]
|
|
(fn [{:keys [db user]} [_]]
|
|
{:db (dissoc db :report)
|
|
:graphql {:token user
|
|
:query-obj {:venia/queries [[:balance-sheet
|
|
(assoc (:data db)
|
|
:client-id (:id @(re-frame/subscribe [::subs/client])))
|
|
[[:balance-sheet-accounts [:name :amount :account-type :id :numeric-code]]
|
|
[:comparable-balance-sheet-accounts [:name :amount :account-type :id :numeric-code]]]]]}
|
|
|
|
:owns-state {:single ::page}
|
|
:on-success [::received]}}))
|
|
|
|
|
|
(re-frame/reg-event-fx
|
|
::investigate-clicked
|
|
(fn [{:keys [db]} [_ {:keys [from-numeric-code to-numeric-code date-range] :as g}]]
|
|
(println g)
|
|
|
|
{:db (-> db (assoc ::ledger-list-active? true))
|
|
:dispatch [::data-page/additional-params-changed ::ledger {:client-id (:id @(re-frame/subscribe [::subs/client]))
|
|
:from-numeric-code from-numeric-code
|
|
:to-numeric-code to-numeric-code
|
|
:date-range {:start "2000-01-01"
|
|
:end date-range}}]}))
|
|
|
|
(re-frame/reg-event-fx
|
|
::ledger-params-change
|
|
[with-user]
|
|
(fn [{:keys [user]} [_ ledger-params]]
|
|
(when (seq ledger-params)
|
|
{:graphql {:token user
|
|
:owns-state {:single [::data-page/page ::ledger]}
|
|
:query-obj {:venia/queries [[:ledger-page
|
|
{:filters (data-params->query-params ledger-params)}
|
|
[[:journal-entries [:id
|
|
:source
|
|
:original-entity
|
|
:amount
|
|
:alternate-description
|
|
[:vendor
|
|
[:name :id]]
|
|
[:client
|
|
[:name :id]]
|
|
[:line-items
|
|
[:id :debit :credit :location :running-balance
|
|
[:account [:id :name]]]]
|
|
:date]]
|
|
:total
|
|
:start
|
|
:end]]]}
|
|
:on-success (fn [result]
|
|
[::data-page/received ::ledger (set/rename-keys (:ledger-page result)
|
|
{:journal-entries :data})])}})))
|
|
|
|
(re-frame/reg-event-fx
|
|
::unmounted-balance-sheet
|
|
(fn [_ _]
|
|
{:dispatch [::data-page/dispose ::ledger]
|
|
::track/dispose {:id ::ledger-params}}))
|
|
|
|
(re-frame/reg-event-fx
|
|
::mounted-balance-sheet
|
|
(fn [{:keys [db]} _]
|
|
{:db (forms/start-form db ::form {:date (date->str (local-now) standard)
|
|
:comparison-date (date->str (t/minus (local-now) (t/years 1)) standard)
|
|
:include-comparison true})
|
|
::track/register {:id ::ledger-params
|
|
:subscription [::data-page/params ::ledger]
|
|
:event-fn (fn [params] [::ledger-params-change params])}}))
|
|
|
|
|
|
(def balance-sheet-form (forms/vertical-form {:can-submit [::can-submit]
|
|
:change-event [::change]
|
|
:submit-event [::report-requested]
|
|
:id ::form}))
|
|
|
|
(defn report-form []
|
|
(let [{:keys [form-inline raw-field]} balance-sheet-form
|
|
{:keys [data]} @(re-frame/subscribe [::forms/form ::form])]
|
|
(form-inline {}
|
|
[:div
|
|
[status/status-notification {:statuses [[::status/single ::page]]}]
|
|
[:div.report-controls
|
|
[:div.level
|
|
[:div.level-left
|
|
[:div.level-item
|
|
[:div.control
|
|
[:p.help "Date"]
|
|
(raw-field
|
|
[date-picker-friendly {:type "date"
|
|
:field [:date]}])]]
|
|
[:div.level-item
|
|
[:div.control
|
|
[:div.mt-3]
|
|
[switch-field {:id "include-comparison"
|
|
:checked (:include-comparison data)
|
|
:on-change (fn [e]
|
|
(re-frame/dispatch [::change [:include-comparison] (.-checked (.-target e))]))
|
|
:label "Include comparison"
|
|
:type "checkbox"}]]]
|
|
[:div.level-item
|
|
|
|
(when (boolean (:include-comparison data))
|
|
[:div.control
|
|
[:p.help "Comparison Date"]
|
|
(raw-field
|
|
[date-picker-friendly {:type "date"
|
|
:field [:comparison-date]}])])]]
|
|
[:div.level-right
|
|
[:div.buttons
|
|
|
|
(when @(re-frame/subscribe [::subs/is-admin?])
|
|
[:button.button.is-secondary {:on-click (dispatch-event [::export-pdf])} "Export"])
|
|
[:button.button.is-primary "Run"]]]]]])))
|
|
|
|
(defn balance-sheet-report [{:keys [args report-data]}]
|
|
(let [pnl-data (concat (->> (:balance-sheet-accounts report-data)
|
|
(map (fn [b]
|
|
(assoc b
|
|
:period (:date args)
|
|
:amount (js/parseFloat (:amount b))))))
|
|
(->> (:comparable-balance-sheet-accounts report-data)
|
|
(map (fn [b]
|
|
(assoc b
|
|
:period (:comparison-date args)
|
|
:amount (js/parseFloat (:amount b)))))))
|
|
|
|
client-names (->> @(re-frame/subscribe [::subs/clients-by-id])
|
|
(map (fn [[k v]]
|
|
[k (:name v)]))
|
|
(into {}))
|
|
pnl-data (l-reports/->PNLData args pnl-data client-names)
|
|
report (l-reports/summarize-balance-sheet pnl-data)]
|
|
[rtable/table {:widths (into [30 13
|
|
(when (:include-comparison args)
|
|
13)
|
|
(when (:include-comparison args)
|
|
13)])
|
|
:click-event ::investigate-clicked
|
|
:table report}]))
|
|
|
|
(defn balance-sheet-content []
|
|
(let [current-client @(re-frame/subscribe [::subs/client])
|
|
status @(re-frame/subscribe [::status/single ::page])
|
|
{params :data report :report} @(re-frame/subscribe [::forms/form ::form])]
|
|
(if current-client
|
|
[:div.is-inline
|
|
[status/status-notification {:statuses [[::status/single ::page]]}]
|
|
[report-form]
|
|
|
|
|
|
[status/big-loader status]
|
|
(when (and (not= :loading (:state status))
|
|
report)
|
|
[balance-sheet-report {:args (assoc params
|
|
:periods (filter identity (cond-> [(:date params)]
|
|
(:include-comparison params) (conj (:comparison-date params)))))
|
|
:report-data report}])]
|
|
[:div
|
|
[:h1.title "Balance sheet"]
|
|
[:h2.subtitle "Please choose a client first"]])))
|
|
|
|
(defn ledger-list [_ ]
|
|
[:div [:a.delete.is-pulled-right {:on-click (dispatch-event [::ledger-list-closing])}]
|
|
[:div
|
|
[:h1.title "Ledger entries"]
|
|
[ledger-table/table {:id :ledger
|
|
:data-page ::ledger}]]])
|
|
|
|
(defn balance-sheet-page []
|
|
(reagent/create-class
|
|
{:display-name "balance-sheet-page"
|
|
:component-did-mount #(re-frame/dispatch [::mounted-balance-sheet])
|
|
:component-will-unmount #(re-frame/dispatch [::unmounted-balance-sheet])
|
|
:reagent-render
|
|
(fn []
|
|
(let [ledger-list-active? @(re-frame/subscribe [::ledger-list-active?])
|
|
user (re-frame/subscribe [::subs/user])]
|
|
(if (not= "manager" (:user/role @user))
|
|
[side-bar-layout
|
|
{:side-bar [ledger-side-bar]
|
|
:main [balance-sheet-content]
|
|
:right-side-bar [appearing-side-bar
|
|
{:visible? ledger-list-active?}
|
|
[ledger-list]]}]
|
|
[:div "Not authorized"])))}))
|