diff --git a/src/clj/auto_ap/graphql.clj b/src/clj/auto_ap/graphql.clj index 52f98c63..eb7e141c 100644 --- a/src/clj/auto_ap/graphql.clj +++ b/src/clj/auto_ap/graphql.clj @@ -68,6 +68,7 @@ :balance_sheet_account {:fields {:id {:type 'String} :amount {:type 'String} + :location {:type 'String} :numeric_code {:type 'Int} :account_type {:type :account_type} :name {:type 'String}}} diff --git a/src/clj/auto_ap/graphql/ledger.clj b/src/clj/auto_ap/graphql/ledger.clj index e17c8d07..b86aa54e 100644 --- a/src/clj/auto_ap/graphql/ledger.clj +++ b/src/clj/auto_ap/graphql/ledger.clj @@ -53,6 +53,7 @@ {:name (str (or (:bank-account/name account) (:account/name account)) (when-not (#{"A" } location) (str "-" location))) + :location location :id (str (:db/id account) "-" location) :numeric-code (or (:account/numeric-code account) (and (:bank-account/type account) @@ -106,39 +107,11 @@ starting-accounts (roll-up starting-results) ending-accounts (roll-up ending-results) - - - accounts (reduce-kv - (fn [result account line-item] - (update-in result [(cond - (expense-account? account) - "Expenses" - - (credit-account? account) - "Liabilities" - (debit-account? account) - "Assets") - - (if (credit-account? account) - "Accounts Payable" - "1100 Cash and Bank Accounts" ) - ] - conj - (update line-item :amount #(- % (:amount (starting-accounts account 0) 0)) ) - )) - {} - ending-accounts) - ] + pnl starting-accounts + comparable-pnl ending-accounts] (->graphql - {:balance-sheet-groupings - (-> [] - - (into (->> (get accounts "Expenses") - (map (fn [[n accounts]] - {:name n - :grouping-type "Expenses" - :accounts accounts} - )))))}))) + {:balance-sheet-accounts pnl + :comparable-balance-sheet-accounts comparable-pnl}))) #_(get-profit-and-loss nil {:client_id [:client/code "CBC"] :from_date "2018-01-01" diff --git a/src/cljs/auto_ap/views/pages/ledger/profit_and_loss.cljs b/src/cljs/auto_ap/views/pages/ledger/profit_and_loss.cljs index a536b52b..e98034b8 100644 --- a/src/cljs/auto_ap/views/pages/ledger/profit_and_loss.cljs +++ b/src/cljs/auto_ap/views/pages/ledger/profit_and_loss.cljs @@ -2,12 +2,25 @@ (:require [auto-ap.subs :as subs] [auto-ap.views.components.layouts :refer [side-bar-layout]] [goog.string :as gstring] - [auto-ap.utils :refer [dollars-0?]] + [auto-ap.utils :refer [dollars-0? by ]] [auto-ap.views.pages.ledger.side-bar :refer [ledger-side-bar]] - [auto-ap.views.utils :refer [date->str date-picker bind-field standard dispatch-event local-now]] + [auto-ap.views.utils :refer [date->str date-picker bind-field standard dispatch-event local-now ->$ str->date]] [cljs-time.core :as t] [re-frame.core :as re-frame])) +(re-frame/reg-sub + ::locations + (fn [db] + (->> db + ::report + :balance-sheet-accounts + (map :location) + (concat (->> db + ::report + :comparable-balance-sheet-accounts + (map :location))) + (set) + (sort)))) (re-frame/reg-sub ::report @@ -20,19 +33,42 @@ (-> db ::loading))) (re-frame/reg-sub - ::assets - (fn [db] - (->> db ::report :balance-sheet-groupings (filter (fn [{:keys [grouping-type]}] (= "Assets" grouping-type)))))) + ::accounts + (fn [db [_ type only-location]] + (->> db + ::report + :balance-sheet-accounts + (map #(update % :amount js/parseFloat)) + (filter (fn [{:keys [account-type location ]}] + (and (= only-location location) + (= type account-type)))) + (sort-by :numeric-code)))) + + (re-frame/reg-sub - ::expenses - (fn [db] - (->> db ::report :balance-sheet-groupings (filter (fn [{:keys [grouping-type]}] (= "Expenses" grouping-type)))))) + ::accounts-by-id + (fn [db [_ type only-location]] + (->> db + ::report + :balance-sheet-accounts + (map #(update % :amount js/parseFloat)) + (filter (fn [{:keys [account-type location]}] + (and (= only-location location) + (= type account-type)))) + (by :id)))) (re-frame/reg-sub - ::liabilities - (fn [db] - (->> db ::report :balance-sheet-groupings (filter (fn [{:keys [grouping-type]}] (= "Liabilities" grouping-type)))))) + ::comparable-accounts-by-id + (fn [db [_ type only-location]] + (->> db + ::report + :comparable-balance-sheet-accounts + (map #(update % :amount js/parseFloat)) + (filter (fn [{:keys [account-type location]}] + (and (= only-location location) + (= type account-type)))) + (by :id)))) (re-frame/reg-event-db ::received @@ -57,7 +93,8 @@ {:client-id (:id @(re-frame/subscribe [::subs/client])) :from-date (:from-date params) :to-date (:to-date params)} - [[:balance-sheet-groupings [:grouping-type :name [:accounts [:name :amount]]]]]]]} + [[:balance-sheet-accounts [:name :amount :account-type :id :numeric-code :location]] + [:comparable-balance-sheet-accounts [:name :amount :account-type :id :numeric-code :location]]]]]} :on-success [::received]}})) (re-frame/reg-event-fx @@ -74,33 +111,58 @@ :from-date from :to-date to :selected selected)]})) +(def groupings + {:expense [["Expenses" 4000 4999] + ["Expenses 2" 5000 5999] + ["Expenses 3" 6000 6999] + ["Expenses 4" 7000 7999] + ["Expenses 5" 8000 8999]]}) -(defn grouping [groupings] +(defn grouping [{:keys [header accounts comparable-accounts groupings]}] - [:table.table - [:tbody - (for [grouping groupings] - ^{:key "items"} - (list - ^{:key "heading"} - [:tr [:td {:col-span "2"} "----" (:name grouping) "----"]] - (for [account (:accounts grouping)] - - (when (not (dollars-0? (js/parseFloat (:amount account)))) - ^{:key (:name account)} - [:tr - [:td (:name account) ] - [:td.has-text-right (gstring/format "$%.2f" (:amount account))]])) - - ^{:key "footing"} - [:tr [:td "----" (:name grouping) "----"] - [:td.has-text-right - (->> grouping - :accounts - (map :amount) - (map #(js/parseFloat %)) - (reduce + 0) - (gstring/format "$%.2f" ))]]))]]) + (for [[grouping-name from to] groupings + :let [matching-accounts (filter + #(<= from (:numeric-code %) to) + accounts)] + :when (seq matching-accounts) + ] + (list + [:tr [:th "---" grouping-name "---"] + [:td] + [:td] + [:td] + ] + (for [account matching-accounts] + [:tr [:td (:name account)] + [:td.has-text-right (->$ (:amount account))] + [:td.has-text-right (->$ (:amount (get comparable-accounts (:id account)) 0))] + [:td.has-text-right (->$ (- (:amount account ) (:amount (get comparable-accounts (:id account)) 0)))]]) + [:tr [:th "---" grouping-name "---"] + [:th.has-text-right.total (->$ (reduce + 0 (map :amount + matching-accounts))) ] + [:th.has-text-right.total (->$ (reduce + 0 (map #(:amount (get comparable-accounts (:id %)) 0) + matching-accounts)))] + [:th.has-text-right.total (->$ (reduce + 0 + (map #(- (:amount % ) (:amount (get comparable-accounts (:id %)) 0)) + matching-accounts)))] + [:td] + ]))) + +(defn overall-grouping [type title location] + (list + [:tr [:th.has-text-centered title] + [:td] + [:td] + [:td]] + (grouping {:accounts @(re-frame/subscribe [::accounts type location]) + :groupings (type groupings) + :comparable-accounts @(re-frame/subscribe [::comparable-accounts-by-id type location]) + }) + [:tr [:th.has-text-centered title] + [:th.has-text-right (->$ (reduce + 0 (map :amount @(re-frame/subscribe [::accounts type location]))))] + [:th.has-text-right (->$ (reduce + 0 (map :amount (vals @(re-frame/subscribe [::comparable-accounts-by-id type location])))))] + [:th.has-text-right (->$ (- (reduce + 0 (map :amount @(re-frame/subscribe [::accounts type location]))) + (reduce + 0 (map :amount (vals @(re-frame/subscribe [::comparable-accounts-by-id type location]))))))]])) (def profit-and-loss-content (with-meta @@ -200,9 +262,17 @@ (if @(re-frame/subscribe [::loading]) [:div [:i.icon.fa.fa-spin.fa-spinner]] [:div - [:h2.title "Expenses"] - [grouping @(re-frame/subscribe [::expenses])]]) - ])) + [:table.table.compact.balance-sheet + (list + [:tr + [:td.has-text-right "Period ending"] + [:td.has-text-right (date->str (str->date (:date params) standard))] + [:td.has-text-right (when (:date params) + (date->str (t/minus (str->date (:date params) standard) (t/years 1))))] + [:td]] + (for [location @(re-frame/subscribe [::locations])] + (list + (overall-grouping :expense location location))))]])])) {:component-will-mount #(re-frame/dispatch-sync [::params-change {:from-date (date->str (t/minus (local-now) (t/period :years 1)) standard) :to-date (date->str (local-now) standard)}]) }))