diff --git a/resources/public/css/main.css b/resources/public/css/main.css index e1dcc896..dcf4709b 100644 --- a/resources/public/css/main.css +++ b/resources/public/css/main.css @@ -296,13 +296,7 @@ nav.navbar .navbar-item.is-active { color: #AAAAAA; text-decoration: none; } -.is-grouped .button { - background-image: linear-gradient(#F8F8F8, #F1F1F1); -} -.is-grouped .button .fa { - font-size: 15px; - color: #AAAAAA; -} + .inbox-messages .card { width: 100%; } diff --git a/src/clj/auto_ap/datomic/migrate/add_general_ledger.clj b/src/clj/auto_ap/datomic/migrate/add_general_ledger.clj index 71c40ad4..4230f88d 100644 --- a/src/clj/auto_ap/datomic/migrate/add_general_ledger.clj +++ b/src/clj/auto_ap/datomic/migrate/add_general_ledger.clj @@ -150,12 +150,9 @@ :where ['[?e :invoice/total]]} :args [(d/db conn)]})) z (->> invoice-ids - (mapv #(ledger/entity-change->ledger (d/db conn) [:invoice %])))] + (mapv #(vector (ledger/entity-change->ledger (d/db conn) [:invoice %]))))] z)) -#_(do @(d/transact (d/connect auto-ap.datomic/uri) - (bulk-load-invoice-ledger (d/connect auto-ap.datomic/uri))) - (println "test")) (defn bulk-load-transaction-ledger [conn] (let [transaction-ids (map first (d/query {:query {:find '[?e] 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 669409d9..9969891b 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 @@ -4,7 +4,7 @@ [goog.string :as gstring] [auto-ap.utils :refer [dollars-0?]] [auto-ap.views.pages.ledger.side-bar :refer [ledger-side-bar]] - [auto-ap.views.utils :refer [date->str date-picker bind-field standard]] + [auto-ap.views.utils :refer [date->str date-picker bind-field standard dispatch-event local-now]] [cljs-time.core :as t] [re-frame.core :as re-frame])) @@ -14,6 +14,11 @@ (fn [db] (-> db ::report))) +(re-frame/reg-sub + ::loading + (fn [db] + (-> db ::loading))) + (re-frame/reg-sub ::assets (fn [db] @@ -32,10 +37,9 @@ (re-frame/reg-event-db ::received (fn [db [_ data]] - (println (:profit-and-loss data)) (-> db (assoc ::report (:profit-and-loss data)) - (assoc-in [:status :loading] false)))) + (assoc-in [::loading] false)))) (re-frame/reg-sub ::params @@ -46,45 +50,57 @@ ::params-change (fn [cofx [_ params]] {:db (-> (:db cofx) - (assoc-in [:status :loading] true) + (assoc-in [::loading] true) (assoc-in [::params] params)) :graphql {:token (-> cofx :db :user) :query-obj {:venia/queries [[:profit-and-loss - (assoc params - :client-id (:id @(re-frame/subscribe [::subs/client]))) + {: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]]]]]]]} :on-success [::received]}})) (re-frame/reg-event-fx ::date-picked (fn [cofx [_ f date]] - (println date) {:dispatch [::params-change (assoc-in @(re-frame/subscribe [::params]) f date)]})) +(re-frame/reg-event-fx + ::range-selected + (fn [cofx [_ from to selected]] + {:dispatch [::params-change (assoc @(re-frame/subscribe [::params]) + :from-date from + :to-date to + :selected selected)]})) + (defn grouping [groupings] [:table.table - (for [grouping groupings] - (list - [:tr [:td {:col-span "2"} "----" (:name grouping) "----"]] - (for [account (:accounts grouping) - - :when [(not (dollars-0? (js/parseFloat (:amount account))))]] - - [:tr - [:td (:name account) ] - [:td.has-text-right (gstring/format "$%.2f" (:amount account))]]) - - [:tr [:td "----" (:name grouping) "----"] - [:td.has-text-right - (->> grouping - :accounts - (map :amount) - (map #(js/parseFloat %)) - (reduce + 0) - (gstring/format "$%.2f" ))]]))]) + [: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" ))]]))]]) (def profit-and-loss-content (with-meta @@ -92,49 +108,107 @@ (let [current-client @(re-frame/subscribe [::subs/client]) user @(re-frame/subscribe [::subs/user]) params @(re-frame/subscribe [::params])] + [:div [:h1.title "Profit and Loss"] - [:div.field - [:p.help "From"] - [bind-field - [date-picker {:class-name "input" - :class "input" - :format-week-number (fn [] "") - :previous-month-button-label "" - :placeholder "mm/dd/yyyy" - :next-month-button-label "" - :next-month-label "" - :type "date" - :field [:from-date] - :event [::date-picked] - :popper-props (clj->js {:placement "right"}) - :subscription params}]]] + [:h2.title.is-4 "Range"] + [:div + [:div.field.is-grouped + [:p.control + [:a.button + {:class (when (= (:selected params) "Last week") "is-active") + :on-click (dispatch-event [::range-selected + (date->str (t/minus (local-now) (t/period :days 7)) standard) + (date->str (local-now) standard) + "Last week"])} + "Last week"]] + [:p.control + [:a.button + {:class (when (= (:selected params) "Week to date") "is-active") + :on-click (dispatch-event [::range-selected + (date->str (loop [current (local-now)] + (if (= 7 (t/day-of-week current)) + current + (recur (t/minus current (t/period :days 1))))) + standard) + (date->str (local-now) standard) + "Week to date"])} + "Week to date"]] + [:p.control + [:a.button + {:class (when (= (:selected params) "Month to date") "is-active") + :on-click (dispatch-event [::range-selected + (date->str (t/local-date (t/year (local-now)) + (t/month (local-now)) + 1) + standard) + (date->str (local-now) standard) + "Month to date"])} + "Month to date"]] + [:p.control + [:a.button + {:class (when (= (:selected params) "Year to date") "is-active") + :on-click (dispatch-event [::range-selected + (date->str (t/local-date (t/year (local-now)) + 1 + 1) + standard) + (date->str (local-now) standard) + "Year to date"])} + "Year to date"]] + [:p.control + [:a.button + {:class (when (= (:selected params) "Full year") "is-active") + :on-click (dispatch-event [::range-selected + (date->str (t/minus (local-now) (t/period :years 1)) + standard) + (date->str (local-now) standard) + "Full year"])} + "Full year"]]]] +[:div.field.is-grouped + [:p.control + [:p.help "From"] + [bind-field + [date-picker {:class-name "input" + :class "input" + :format-week-number (fn [] "") + :previous-month-button-label "" + :placeholder "mm/dd/yyyy" + :next-month-button-label "" + :next-month-label "" + :type "date" + :field [:from-date] + :event [::date-picked] + :popper-props (clj->js {:placement "right"}) + :subscription params}]]] - [:div.field - [:p.help "To"] - [bind-field - [date-picker {:class-name "input" - :class "input" - :format-week-number (fn [] "") - :previous-month-button-label "" - :placeholder "mm/dd/yyyy" - :next-month-button-label "" - :next-month-label "" - :type "date" - :field [:to-date] - :event [::date-picked] - :popper-props (clj->js {:placement "right"}) - :subscription params}]]] - - [:h2.title "Assets"] - [grouping @(re-frame/subscribe [::assets])] - [:h2.title "Expenses"] - [grouping @(re-frame/subscribe [::expenses])] - [:h2.title "Liabilities"] - [grouping @(re-frame/subscribe [::liabilities])] + [:p.control + [:p.help "To"] + [bind-field + [date-picker {:class-name "input" + :class "input" + :format-week-number (fn [] "") + :previous-month-button-label "" + :placeholder "mm/dd/yyyy" + :next-month-button-label "" + :next-month-label "" + :type "date" + :field [:to-date] + :event [::date-picked] + :popper-props (clj->js {:placement "right"}) + :subscription params}]]]] + (if @(re-frame/subscribe [::loading]) + [:div [:i.icon.fa.fa-spin.fa-spinner]] + [:div + [:h2.title "Assets"] + [grouping @(re-frame/subscribe [::assets])] + [:h2.title "Expenses"] + [grouping @(re-frame/subscribe [::expenses])] + [:h2.title "Liabilities"] + [grouping @(re-frame/subscribe [::liabilities])]]) ])) - {:component-will-mount #(re-frame/dispatch-sync [::params-change {:from-date (date->str (t/minus (t/now) (t/period :years 1)) standard) - :to-date (date->str (t/now) standard)}]) })) + {: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)}]) })) (defn profit-and-loss-page [] [side-bar-layout diff --git a/src/cljs/auto_ap/views/utils.cljs b/src/cljs/auto_ap/views/utils.cljs index c71aeea3..18610e07 100644 --- a/src/cljs/auto_ap/views/utils.cljs +++ b/src/cljs/auto_ap/views/utils.cljs @@ -9,7 +9,8 @@ [auto-ap.events :as events] [auto-ap.subs :as subs] [cljs-time.format :as format] - [goog.i18n.NumberFormat.Format]) + [goog.i18n.NumberFormat.Format] + [cljs-time.core :as t]) (:import (goog.i18n NumberFormat) (goog.i18n.NumberFormat Format))) @@ -184,3 +185,6 @@ (if (or @final-state visible?) (first children) [:span])]))) + +(defn local-now [] + (t/to-default-time-zone (t/now)))