diff --git a/src/clj/auto_ap/graphql/ledger.clj b/src/clj/auto_ap/graphql/ledger.clj index 164024aa..98d6e798 100644 --- a/src/clj/auto_ap/graphql/ledger.clj +++ b/src/clj/auto_ap/graphql/ledger.clj @@ -505,16 +505,40 @@ (defn get-journal-detail-report [context input _] - (clojure.pprint/pprint - (for [category (:categories input)] - {:category category - :journal_entries (:journal_entries (get-ledger-page context {:filters (doto {:client_ids (:client_ids input) - :date_range (:date_range input) - :from_numeric_code (get-in l-reports/ranges [category 0]) - :to_numeric_code (get-in l-reports/ranges [category 1]) - :per_page Integer/MAX_VALUE} - clojure.pprint/pprint)} - nil))}))) + {:categories + (for [client-id (:client_ids input) + :let [account-lookup (build-account-lookup client-id) + c (d/pull (d/db conn) '[:client/locations] client-id) ] + location (:client/locations c) + category (:categories input) + :let [journal-entries (->> (get-ledger-page context + {:filters {:client_id client-id + :location location + :date_range (:date_range input) + :from_numeric_code (get-in l-reports/ranges [category 0]) + :to_numeric_code (get-in l-reports/ranges [category 1]) + :per_page Integer/MAX_VALUE}} + nil) + :journal_entries + (map (fn [je] + (update je :line_items + (fn [jels] + (into [] + (filter (fn [jel] + (when-let [account (account-lookup (:id (:account jel)))] + (and + (<= (get-in l-reports/ranges [category 0]) + (:numeric_code account) + (get-in l-reports/ranges [category 1])) + (= location (:location jel))))) + jels )))))) + (group-by #(account-lookup (get-in % [:line_items 0 :account :id]))))] + [account journal-entries] journal-entries] + {:category category + :client_id client-id + :location location + :account account + :journal_entries journal-entries})}) (def objects @@ -584,6 +608,9 @@ :journal_detail_report_category {:fields {:category {:type :ledger_category} + :account {:type :account} + :client_id {:type :id} + :location {:type 'String} :journal_entries {:type '(list :journal_entry)}}} :journal_detail_report {:fields {:categories {:type '(list :journal_detail_report_category)}}}}) diff --git a/src/cljc/auto_ap/ledger/reports.cljc b/src/cljc/auto_ap/ledger/reports.cljc index ba642746..3b289bcb 100644 --- a/src/cljc/auto_ap/ledger/reports.cljc +++ b/src/cljc/auto_ap/ledger/reports.cljc @@ -3,13 +3,17 @@ (:clj [(:require [auto-ap.time :as atime] + [auto-ap.time-utils :refer [user-friendly-date]] [auto-ap.utils :refer [dollars-0?]] - [clojure.string :as str])] + [clojure.string :as str] + [auto-ap.time-utils :refer [user-friendly-date]] + )] :cljs [(:require [auto-ap.utils :refer [dollars-0?]] [auto-ap.views.utils :as au] - [clojure.string :as str])])) + [clojure.string :as str] + [auto-ap.time-utils :refer [user-friendly-date]])])) (defn date->str [d] #?(:clj @@ -551,4 +555,35 @@ :rows table})) +(defn journal-detail-report [args data client-codes] + {:header [[{:value "Date"} + {:value "Description"} + {:value "Debit"} + {:value "Credit"} + {:value "Running Balance"}]] + :rows (reduce + (fn [rows category] + (into rows + (cons [{:value (str (client-codes (:client-id category)) " - " (:location category) " - " (name (:category category)) " - " (:name (:account category)) ) + + :colspan 5}] + (map + (fn [je] + [{:value (user-friendly-date (:date je))} + {:value (or (:description je) + (:name (:vendor je)))} + {:value (get-in je [:line-items 0 :debit]) + :format :dollar} + {:value (get-in je [:line-items 0 :credit]) + :format :dollar} + {:value (get-in je [:line-items 0 :running-balance]) + :format :dollar}]) + (:journal-entries category)))) + + ) + [] + (:categories data))} + ) + + (defrecord PNLData [args data client-codes]) diff --git a/src/cljc/auto_ap/time_utils.cljc b/src/cljc/auto_ap/time_utils.cljc index a99dafe5..c39d3df3 100644 --- a/src/cljc/auto_ap/time_utils.cljc +++ b/src/cljc/auto_ap/time_utils.cljc @@ -1,6 +1,13 @@ (ns auto-ap.time-utils (:require #?(:clj [clj-time.core :as time] - :cljs [cljs-time.core :as time]))) + :cljs [cljs-time.core :as time]) + #?(:cljs [cljs-time.format :as format] + :clj [clj-time.format :as format]))) + +(def pretty (format/formatter "MM/dd/yyyy")) + +(defn user-friendly-date [d] + (some->> d (format/unparse pretty))) (defn next-dom [date dom] (when date diff --git a/src/cljs/auto_ap/views/pages/ledger/profit_and_loss_detail.cljs b/src/cljs/auto_ap/views/pages/ledger/profit_and_loss_detail.cljs index 56ebdf6b..f6b9d126 100644 --- a/src/cljs/auto_ap/views/pages/ledger/profit_and_loss_detail.cljs +++ b/src/cljs/auto_ap/views/pages/ledger/profit_and_loss_detail.cljs @@ -32,7 +32,7 @@ ::received [(forms/in-form ::form)] (fn [db [_ data]] - (-> db (assoc :report (:profit-and-loss data))))) + (-> db (assoc :report (:journal-detail-report data))))) ;; EVENTS @@ -63,7 +63,10 @@ [:id :debit :credit :location :running-balance [:account [:id :name]]]] :date]] - :category]]]]]} + :category + :client-id + :location + [:account [:numeric-code :name]]]]]]]} :on-success [::received]} :set-uri-params {:date-range (:date-range (:data db)) :clients (mapv #(select-keys (:client %) [:name :id]) (:clients (:data db))) } @@ -128,10 +131,6 @@ NOTE: Please review the transactions we may have question for you here: https:// (fn [{:keys [db]} [_ & event]] {:db (dissoc db :report)})) - - - - (defn report-control-detail [{:keys [active box which]} children] (when (and @box (= which @active)) @@ -189,36 +188,19 @@ NOTE: Please review the transactions we may have question for you here: https:// (when (not= @!box el) (reset! !box el)))}]]])))) -(defn pnl-report [{:keys [args report-data]}] - (let [pnl-data (->> report-data - :periods - (mapcat (fn [p1 p2] - (map - (fn [a] - (assoc a :period p1 - :amount (js/parseFloat (:amount a))) - ) - (:accounts p2))) - (:periods args))) - client-codes (->> @(re-frame/subscribe [::subs/clients-by-id]) +(defn pnl-detail-report [{:keys [args report-data]}] + (let [client-codes (->> @(re-frame/subscribe [::subs/clients-by-id]) (map (fn [[k v]] [k (:code v)])) (into {})) - pnl-data (l-reports/->PNLData args pnl-data client-codes) - report (l-reports/summarize-pnl pnl-data) - table (rtable/concat-tables (concat (:summaries report) (:details report)))] + report (l-reports/journal-detail-report args report-data client-codes)] [:div - [:h1.title "Profit and Loss - " (str/join ", " (map (comp :name :client) (:clients args)))] + [:h1.title "Profit and Loss Detail - " (str/join ", " (map (comp :name :client) (:clients args)))] (when (:warning report) [:div.notification.is-warning.is-light (:warning report)]) - [rtable/table {:widths (into [20] (take (dec (rtable/cell-count table)) - (mapcat identity - (repeat - (if (-> pnl-data :args :include-deltas) - [13 6 13] - [13 6]))))) - :table table}]])) + [rtable/table {:widths [20 20 60 20 20] + :table report}]])) ;; TODO Break out one category per location @@ -234,8 +216,8 @@ NOTE: Please review the transactions we may have question for you here: https:// [status/big-loader status] (when (and (not= :loading (:state status)) report) - [pnl-report {:report-data report - :args data}])])) + [pnl-detail-report {:report-data report + :args data}])])) (re-frame/reg-event-fx diff --git a/src/cljs/auto_ap/views/pages/ledger/side_bar.cljs b/src/cljs/auto_ap/views/pages/ledger/side_bar.cljs index 3683450e..ca4166c9 100644 --- a/src/cljs/auto_ap/views/pages/ledger/side_bar.cljs +++ b/src/cljs/auto_ap/views/pages/ledger/side_bar.cljs @@ -30,12 +30,13 @@ [:span {:class "icon icon-performance-increase-1" :style {:font-size "25px"}}] [:span {:class "name"} "Profit & Loss"]]] - [:li.menu-item - [:a.item {:href (bidi/path-for routes/routes :profit-and-loss-detail) - :class [(active-when ap = :profit-and-loss-detail)]} + (when (= "admin" (:user/role user)) + [:li.menu-item + [:a.item {:href (bidi/path-for routes/routes :profit-and-loss-detail) + :class [(active-when ap = :profit-and-loss-detail)]} - [:span {:class "icon icon-performance-increase-1" :style {:font-size "25px"}}] - [:span {:class "name"} "Profit & Loss Detail"]]] + [:span {:class "icon icon-performance-increase-1" :style {:font-size "25px"}}] + [:span {:class "name"} "Profit & Loss Detail"]]]) [:li.menu-item [:a.item {:href (bidi/path-for routes/routes :balance-sheet) :class [(active-when ap = :balance-sheet)]}