Files
integreat/src/cljs/auto_ap/views/pages/ledger/balance_sheet.cljs

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"])))}))