diff --git a/src/clj/auto_ap/datomic/invoices.clj b/src/clj/auto_ap/datomic/invoices.clj index 37a177a8..c2c30902 100644 --- a/src/clj/auto_ap/datomic/invoices.clj +++ b/src/clj/auto_ap/datomic/invoices.clj @@ -62,6 +62,16 @@ '[(<= ?date ?end-date)]]} :args [(c/to-date (:end (:date-range args)))]}) + (:start (:due-range args)) (merge-query {:query {:in '[?start-due] + :where ['[?e :invoice/due ?due] + '[(>= ?due ?start-due)]]} + :args [(c/to-date (:start (:due-range args)))]}) + + (:end (:due-range args)) (merge-query {:query {:in '[?end-due] + :where ['[?e :invoice/due ?due] + '[(<= ?due ?end-due)]]} + :args [(c/to-date (:end (:due-range args)))]}) + (:import-status args) (merge-query {:query {:in ['?import-status] :where ['[?e :invoice/import-status ?import-status]]} diff --git a/src/clj/auto_ap/graphql.clj b/src/clj/auto_ap/graphql.clj index 1a358861..299772df 100644 --- a/src/clj/auto_ap/graphql.clj +++ b/src/clj/auto_ap/graphql.clj @@ -394,6 +394,7 @@ :invoice_page {:type '(list :invoice_page) :args {:import_status {:type 'String} :date_range {:type :date_range} + :due_range {:type :date_range} :status {:type :invoice_status} :client_id {:type :id} :vendor_id {:type :id} @@ -871,11 +872,10 @@ true (merge-query {:query {:where ['[?i :invoice/client ?c] '[?i :invoice/outstanding-balance ?outstanding-balance] '[?i :invoice/total ?total] - '[?i :invoice/date ?date] + '[?i :invoice/due ?date] '[(.toInstant ^java.util.Date ?date) ?d2] '[(.between java.time.temporal.ChronoUnit/DAYS (java.time.Instant/now) ?d2 ) ?d3] - '[(+ 30 ?d3) ?d4] - '[(auto-ap.graphql/categorize ?d4) ?name]]}}) + '[(auto-ap.graphql/categorize ?d3) ?name]]}}) true (d/query )) result (group-by first result)] diff --git a/src/cljs/auto_ap/effects.cljs b/src/cljs/auto_ap/effects.cljs index 393ac862..7c8d9362 100644 --- a/src/cljs/auto_ap/effects.cljs +++ b/src/cljs/auto_ap/effects.cljs @@ -17,6 +17,22 @@ (fn [uri] (pushy/set-token! p/history uri))) +(re-frame/reg-fx + :set-uri-params + (fn [uri-params] + (pushy/set-token! p/history + (str (.-protocol (.-location js/window)) "//" (.-host (.-location js/window)) (.-pathname (.-location js/window)) + "?" + (cemerick.url/map->query (into {} (filter (fn [[k v]] v) uri-params))) + #_(reduce-kv (fn [result k v] + (if v + (str (or result "?") + (when result "&") + (name k) "=" (js/encodeURI v)) + result)) + nil + uri-params))))) + (re-frame/reg-fx :new-window (fn [url] diff --git a/src/cljs/auto_ap/events.cljs b/src/cljs/auto_ap/events.cljs index 8224a506..7235050b 100644 --- a/src/cljs/auto_ap/events.cljs +++ b/src/cljs/auto_ap/events.cljs @@ -4,6 +4,7 @@ [auto-ap.subs :as subs] [auto-ap.routes :as routes] [auto-ap.effects :as effects] + [auto-ap.utils :refer [by]] [venia.core :as v] [bidi.bidi :as bidi] @@ -38,9 +39,7 @@ {:db (assoc db/default-db :active-page handler :last-client-id (.getItem js/localStorage "last-client-id") - :query-params (->> (:query (url (.-location js/window))) - (map (fn [[k v]] [(keyword k) v])) - (into {})) + :query-params (auto-ap.views.utils/query-params) :user token) :graphql {:token token :query-obj {:venia/queries [[:client diff --git a/src/cljs/auto_ap/history.cljs b/src/cljs/auto_ap/history.cljs index b5c74ef9..6bea77a5 100644 --- a/src/cljs/auto_ap/history.cljs +++ b/src/cljs/auto_ap/history.cljs @@ -11,9 +11,7 @@ (defn- dispatch-route [matched-route] (println "Matched route" matched-route) - (re-frame/dispatch [:auto-ap.events/set-active-page (:handler matched-route) (->> (:query (url (.-location js/window))) - (map (fn [[k v]] [(keyword k) v])) - (into {}))])) + (re-frame/dispatch [:auto-ap.events/set-active-page (:handler matched-route) (auto-ap.views.utils/query-params)])) (def history (pushy/pushy dispatch-route parse-url)) diff --git a/src/cljs/auto_ap/views/components/invoice_table.cljs b/src/cljs/auto_ap/views/components/invoice_table.cljs index 011f18dc..78603ed0 100644 --- a/src/cljs/auto_ap/views/components/invoice_table.cljs +++ b/src/cljs/auto_ap/views/components/invoice_table.cljs @@ -59,10 +59,17 @@ :end]]]}) (re-frame/reg-sub - ::table-params + ::specific-table-params (fn [db] (::table-params db))) +(re-frame/reg-sub + ::table-params + :<- [::specific-table-params] + :<- [::subs/query-params] + (fn [[specific-table-params query-params]] + (merge (select-keys query-params #{:start :sort}) specific-table-params ))) + (re-frame/reg-event-fx ::params-changed [(re-frame/path [::table-params])] diff --git a/src/cljs/auto_ap/views/components/invoices/side_bar.cljs b/src/cljs/auto_ap/views/components/invoices/side_bar.cljs index 4217a6cf..df6396ed 100644 --- a/src/cljs/auto_ap/views/components/invoices/side_bar.cljs +++ b/src/cljs/auto_ap/views/components/invoices/side_bar.cljs @@ -9,21 +9,41 @@ [auto-ap.routes :as routes] [auto-ap.views.components.date-range-filter :refer [date-range-filter]] [auto-ap.views.components.typeahead :refer [typeahead-entity]] - [auto-ap.views.utils :refer [active-when dispatch-event bind-field horizontal-field date->str str->date pretty standard]] + [auto-ap.views.utils :refer [active-when dispatch-event bind-field horizontal-field date->str str->date pretty standard query-params]] [auto-ap.subs :as subs] [auto-ap.events :as events])) +(re-frame/reg-sub + ::specific-filters + (fn [db ] + (::filters db nil))) (re-frame/reg-sub ::filters - (fn [db ] - (::filters db {}))) + :<- [::specific-filters] + :<- [::subs/vendors-by-id] + :<- [::subs/query-params] + (fn [[specific-filters vendors-by-id query-params] ] + (let [url-filters (-> query-params + (select-keys #{:vendor-id + :date-range + :due-range + :invoice-number-like + :status})) + url-filters {:vendor (when-let [vendor-id (:vendor-id url-filters)] + {:id (str vendor-id) + :name (get-in vendors-by-id [(str vendor-id) :name] "Loading...")}) + :date-range (:date-range url-filters) + :due-range (:due-range url-filters) + :invoice-number-like {:raw (:invoice-number-like url-filters) + :settled (:invoice-number-like url-filters)}}] + (merge url-filters specific-filters )))) (re-frame/reg-sub ::filter :<- [::filters] (fn [filters [_ which]] - (filters which))) + (get filters which))) (re-frame/reg-sub ::filter-params @@ -32,12 +52,13 @@ (fn [[filters ap]] {:vendor-id (:id (:vendor filters)) :date-range (:date-range filters) + :due-range (:due-range filters) :invoice-number-like (:settled (:invoice-number-like filters)) :status (condp = ap - :invoices nil - :unpaid-invoices :unpaid - :paid-invoices :paid - :voided-invoices :voided)})) + :invoices nil + :unpaid-invoices :unpaid + :paid-invoices :paid + :voided-invoices :voided)})) (re-frame/reg-event-fx @@ -125,6 +146,13 @@ [date-range-filter {:on-change-event [::filter-changed :date-range] :value @(re-frame/subscribe [::filter :date-range])}]] + + [:p.menu-label "Due Range"] + [:div + [date-range-filter + {:on-change-event [::filter-changed :due-range] + :value @(re-frame/subscribe [::filter :due-range])}]] + [:p.menu-label "Invoice #"] [:div [invoice-number-filter]]])])) diff --git a/src/cljs/auto_ap/views/pages/home.cljs b/src/cljs/auto_ap/views/pages/home.cljs index dbc4f6d3..79792772 100644 --- a/src/cljs/auto_ap/views/pages/home.cljs +++ b/src/cljs/auto_ap/views/pages/home.cljs @@ -1,10 +1,13 @@ (ns auto-ap.views.pages.home (:require [auto-ap.views.components.layouts :refer [side-bar-layout]] [re-frame.core :as re-frame] + [bidi.bidi :as bidi] + [auto-ap.routes :as routes] [auto-ap.subs :as subs] [cljs-time.core :as t] - [auto-ap.views.utils :refer [local-now date->str]] - [reagent.core :as r])) + [auto-ap.views.utils :refer [local-now date->str standard]] + [reagent.core :as r] + [pushy.core :as pushy])) (def pie-chart (r/adapt-react-class js/Recharts.PieChart)) @@ -47,16 +50,21 @@ ) (defn make-cash-flow-chart [{:keys [width height data] }] - (println data) - [bar-chart {:width width :height height :data data :fill "#FFFFFF" :stackOffset "sign"} - [tool-tip] - [bar {:dataKey "effective-balance" :fill (get colors 1) :stackId "a" :name "Effective Balance"}] - [bar {:dataKey "outstanding-payments" :fill (get colors 0) :stackId "a" :name "Outstanding Payments"}] - [bar {:dataKey "invoices" :fill (get colors 3) :stackId "a" :name "Invoices"}] - - [x-axis {:dataKey "name"}] - [y-axis] - [legend]] + (let [redirect-fn (fn [x] + (pushy/set-token! auto-ap.history/history (str (bidi/path-for routes/routes :unpaid-invoices) "?" (get (js->clj x) "query-params"))) + )] + [bar-chart {:width width :height height :data data :fill "#FFFFFF" :stackOffset "sign"} + [tool-tip] + [bar {:dataKey "effective-balance" :fill (get colors 1) :stackId "a" :name "Effective Balance" + :on-click redirect-fn}] + [bar {:dataKey "outstanding-payments" :fill (get colors 0) :stackId "a" :name "Outstanding Payments" + :on-click redirect-fn}] + [bar {:dataKey "invoices" :fill (get colors 3) :stackId "a" :name "Invoices" + :on-click redirect-fn}] + + [x-axis {:dataKey "name"}] + [y-axis] + [legend]]) ) (re-frame/reg-event-db @@ -99,8 +107,6 @@ (let [due (if (t/before? (:due invoice) (local-now)) (local-now) (:due invoice))] - (println due) - (update result (date->str due) (fn [r] (+ (or r 0.0) (:outstanding-balance invoice)))))) {} @@ -113,14 +119,18 @@ (reduce (fn [[{:keys [effective-balance] } :as acc] day] (let [invoices-due-today (invoices-due-soon (date->str (t/plus start-date (t/days day))) 0.0)] - (conj acc - {:name (date->str (t/plus start-date (t/days day))) - :effective-balance (- effective-balance invoices-due-today) - :invoices (- invoices-due-today)}))) + (let [today (t/plus start-date (t/days day))] + (conj acc + {:name (date->str today) + :effective-balance (- effective-balance invoices-due-today) + :invoices (- invoices-due-today) + :query-params (cemerick.url/map->query {:due-range {:start (date->str today standard) + :end (date->str today standard)}})})))) (list {:name (date->str start-date) :effective-balance effective-balance :invoices (- (invoices-due-soon (date->str start-date) 0.0)) - :outstanding-payments (- outstanding-payments)}) + :outstanding-payments (- outstanding-payments) + :query-params (cemerick.url/map->query {:due-range {:end (date->str start-date standard)}})}) (range 1 7)))))) (re-frame/reg-event-fx diff --git a/src/cljs/auto_ap/views/pages/unpaid_invoices.cljs b/src/cljs/auto_ap/views/pages/unpaid_invoices.cljs index fb914bf2..11d7643b 100644 --- a/src/cljs/auto_ap/views/pages/unpaid_invoices.cljs +++ b/src/cljs/auto_ap/views/pages/unpaid_invoices.cljs @@ -98,14 +98,17 @@ ::params-change [with-user (re-frame/inject-cofx ::inject/sub [::params])] (fn [{::keys [params] :as cofx} _] - (println "params" params) {:db (-> (:db cofx) (assoc-in [:status :loading] true) (assoc-in [::last-params] params)) :graphql {:token (-> cofx :db :user) :query-obj (table/query params ) :on-success [::received] - :on-error [::events/page-failed]}})) + :on-error [::events/page-failed]} + :set-uri-params (dissoc params + :status + :client-id + :import-status)})) (re-frame/reg-event-fx ::unmounted diff --git a/src/cljs/auto_ap/views/utils.cljs b/src/cljs/auto_ap/views/utils.cljs index c017301a..ad4b118a 100644 --- a/src/cljs/auto_ap/views/utils.cljs +++ b/src/cljs/auto_ap/views/utils.cljs @@ -320,3 +320,10 @@ :before (fn [context] (-> context (assoc-in [:coeffects :user] (get-in context [:coeffects :db :user])))))) + +(defn query-params [] + (reduce-kv + (fn [result k v] + (assoc result (keyword k) (cljs.tools.reader.edn/read-string v))) + {} + (:query (cemerick.url/url (.-location js/window)))))