makes it possible to add new vendors.
This commit is contained in:
File diff suppressed because one or more lines are too long
@@ -10,6 +10,7 @@
|
|||||||
[auto-ap.routes.utils
|
[auto-ap.routes.utils
|
||||||
:refer [wrap-client-redirect-unauthenticated]]
|
:refer [wrap-client-redirect-unauthenticated]]
|
||||||
[auto-ap.rule-matching :as rm]
|
[auto-ap.rule-matching :as rm]
|
||||||
|
[auto-ap.client-routes :as client-routes]
|
||||||
[auto-ap.solr :as solr]
|
[auto-ap.solr :as solr]
|
||||||
[auto-ap.ssr-routes :as ssr-routes]
|
[auto-ap.ssr-routes :as ssr-routes]
|
||||||
[auto-ap.ssr.common-handlers :refer [add-new-entity-handler]]
|
[auto-ap.ssr.common-handlers :refer [add-new-entity-handler]]
|
||||||
@@ -229,6 +230,14 @@
|
|||||||
:value (fc/field-value)
|
:value (fc/field-value)
|
||||||
:content-fn (fn [c] (pull-attr (dc/db conn) :vendor/name c))
|
:content-fn (fn [c] (pull-attr (dc/db conn) :vendor/name c))
|
||||||
:x-model "vendorId"})]))
|
:x-model "vendorId"})]))
|
||||||
|
[:div.mb-4
|
||||||
|
[:span.text-sm.text-gray-500 "Can't find the vendor? "
|
||||||
|
(com/link {:href (bidi.bidi/path-for
|
||||||
|
client-routes/routes
|
||||||
|
:new-vendor)
|
||||||
|
:target "new"}
|
||||||
|
"Add new vendor")
|
||||||
|
" in a new window, then return here."]]
|
||||||
|
|
||||||
|
|
||||||
[:div.flex.items-center.gap-2
|
[:div.flex.items-center.gap-2
|
||||||
|
|||||||
@@ -6,7 +6,8 @@
|
|||||||
"needs-activation/" :needs-activation
|
"needs-activation/" :needs-activation
|
||||||
"needs-activation" :needs-activation
|
"needs-activation" :needs-activation
|
||||||
"payments/" :payments
|
"payments/" :payments
|
||||||
"admin/" { "vendors" :admin-vendors}
|
"admin/" {"vendors" :admin-vendors}
|
||||||
|
"vendor/" {"new" :new-vendor}
|
||||||
"invoices/" {"" :invoices
|
"invoices/" {"" :invoices
|
||||||
"import" :import-invoices
|
"import" :import-invoices
|
||||||
"unpaid" :unpaid-invoices
|
"unpaid" :unpaid-invoices
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
[auto-ap.views.pages.ledger.profit-and-loss-detail :refer [profit-and-loss-detail-page]]
|
[auto-ap.views.pages.ledger.profit-and-loss-detail :refer [profit-and-loss-detail-page]]
|
||||||
[auto-ap.views.pages.login :refer [login-page]]
|
[auto-ap.views.pages.login :refer [login-page]]
|
||||||
[auto-ap.views.pages.payments :refer [payments-page]]
|
[auto-ap.views.pages.payments :refer [payments-page]]
|
||||||
[auto-ap.views.pages.home :refer [home-page]]))
|
[auto-ap.views.pages.home :refer [home-page home-page-with-vendor]]))
|
||||||
|
|
||||||
(defmulti page (fn [active-page] active-page))
|
(defmulti page (fn [active-page] active-page))
|
||||||
(defmethod page :unpaid-invoices [_]
|
(defmethod page :unpaid-invoices [_]
|
||||||
@@ -94,6 +94,10 @@
|
|||||||
(defmethod page :index [_]
|
(defmethod page :index [_]
|
||||||
(home-page))
|
(home-page))
|
||||||
|
|
||||||
|
(defmethod page :new-vendor [_]
|
||||||
|
(home-page-with-vendor))
|
||||||
|
|
||||||
|
|
||||||
(defmethod page :login [_]
|
(defmethod page :login [_]
|
||||||
[login-page])
|
[login-page])
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,9 @@
|
|||||||
(:require [auto-ap.routes :as routes]
|
(:require [auto-ap.routes :as routes]
|
||||||
[auto-ap.subs :as subs]
|
[auto-ap.subs :as subs]
|
||||||
[auto-ap.views.components.grid :as grid]
|
[auto-ap.views.components.grid :as grid]
|
||||||
|
[auto-ap.permissions :as p]
|
||||||
[auto-ap.views.components.layouts :refer [side-bar-layout]]
|
[auto-ap.views.components.layouts :refer [side-bar-layout]]
|
||||||
|
[auto-ap.views.components.vendor-dialog :as vendor-dialog]
|
||||||
[auto-ap.history :refer [history]]
|
[auto-ap.history :refer [history]]
|
||||||
[cemerick.url :as url]
|
[cemerick.url :as url]
|
||||||
[auto-ap.views.utils
|
[auto-ap.views.utils
|
||||||
@@ -35,15 +37,14 @@
|
|||||||
(defn make-pie-chart
|
(defn make-pie-chart
|
||||||
[{:keys [width height data]}]
|
[{:keys [width height data]}]
|
||||||
[pie-chart {:width width
|
[pie-chart {:width width
|
||||||
:height height}
|
:height height}
|
||||||
[pie {:fill "#82ca9d"
|
[pie {:fill "#82ca9d"
|
||||||
:data data
|
:data data
|
||||||
:dataKey "value"
|
:dataKey "value"
|
||||||
:inner-radius 20}
|
:inner-radius 20}
|
||||||
(map (fn [_ y]
|
(map (fn [_ y]
|
||||||
^{:key y}
|
^{:key y}
|
||||||
[cell {:key y :fill (colors y)}]) data (range))
|
[cell {:key y :fill (colors y)}]) data (range))]
|
||||||
]
|
|
||||||
[tool-tip]
|
[tool-tip]
|
||||||
[legend]])
|
[legend]])
|
||||||
|
|
||||||
@@ -56,10 +57,9 @@
|
|||||||
[y-axis]
|
[y-axis]
|
||||||
[legend]])
|
[legend]])
|
||||||
|
|
||||||
(defn make-cash-flow-chart [{:keys [width height data] }]
|
(defn make-cash-flow-chart [{:keys [width height data]}]
|
||||||
(let [redirect-fn (fn [x]
|
(let [redirect-fn (fn [x]
|
||||||
(pushy/set-token! history (str (bidi/path-for routes/routes :unpaid-invoices) "?" (get (js->clj x) "query-params")))
|
(pushy/set-token! 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"}
|
[bar-chart {:width width :height height :data data :fill "#FFFFFF" :stackOffset "sign"}
|
||||||
[tool-tip]
|
[tool-tip]
|
||||||
[bar {:dataKey "effective-balance" :fill (get colors 1) :stackId "a" :name "Effective Balance"
|
[bar {:dataKey "effective-balance" :fill (get colors 1) :stackId "a" :name "Effective Balance"
|
||||||
@@ -69,13 +69,12 @@
|
|||||||
[bar {:dataKey "invoices" :fill (get colors 3) :stackId "a" :name "Invoices"
|
[bar {:dataKey "invoices" :fill (get colors 3) :stackId "a" :name "Invoices"
|
||||||
:on-click redirect-fn}]
|
:on-click redirect-fn}]
|
||||||
[bar {:dataKey "credits" :fill (get colors 2) :stackId "a" :name "Upcoming Credits"
|
[bar {:dataKey "credits" :fill (get colors 2) :stackId "a" :name "Upcoming Credits"
|
||||||
:on-click redirect-fn}]
|
:on-click redirect-fn}]
|
||||||
[bar {:dataKey "debits" :fill (get colors 4) :stackId "a" :name "Upcoming Debits"
|
[bar {:dataKey "debits" :fill (get colors 4) :stackId "a" :name "Upcoming Debits"
|
||||||
:on-click redirect-fn}]
|
:on-click redirect-fn}]
|
||||||
[x-axis {:dataKey "name"}]
|
[x-axis {:dataKey "name"}]
|
||||||
[y-axis]
|
[y-axis]
|
||||||
[legend]])
|
[legend]]))
|
||||||
)
|
|
||||||
|
|
||||||
(re-frame/reg-event-db
|
(re-frame/reg-event-db
|
||||||
::received
|
::received
|
||||||
@@ -120,7 +119,7 @@
|
|||||||
(::top-expense-categories db)))
|
(::top-expense-categories db)))
|
||||||
|
|
||||||
(defn sum-by-date [pairs]
|
(defn sum-by-date [pairs]
|
||||||
(reduce
|
(reduce
|
||||||
(fn [result [date amount]]
|
(fn [result [date amount]]
|
||||||
(let [due (if (t/before? date (local-now))
|
(let [due (if (t/before? date (local-now))
|
||||||
(local-now)
|
(local-now)
|
||||||
@@ -156,10 +155,10 @@
|
|||||||
upcoming-debits (sum-by-date (map (fn [i] [(:date i) (:amount i)]) upcoming-debits))
|
upcoming-debits (sum-by-date (map (fn [i] [(:date i) (:amount i)]) upcoming-debits))
|
||||||
start-date (local-now)
|
start-date (local-now)
|
||||||
effective-balance (- beginning-balance outstanding-payments (invoices-due-soon (date->str start-date) 0.0))]
|
effective-balance (- beginning-balance outstanding-payments (invoices-due-soon (date->str start-date) 0.0))]
|
||||||
|
|
||||||
(reverse
|
(reverse
|
||||||
(reduce
|
(reduce
|
||||||
(fn [[{:keys [effective-balance credits-yesterday] } :as acc] day]
|
(fn [[{:keys [effective-balance credits-yesterday]} :as acc] day]
|
||||||
(let [invoices-due-today (invoices-due-soon (date->str (t/plus start-date (t/days day))) 0.0)
|
(let [invoices-due-today (invoices-due-soon (date->str (t/plus start-date (t/days day))) 0.0)
|
||||||
credits-due-today (upcoming-credits (date->str (t/plus start-date (t/days day))) 0.0)
|
credits-due-today (upcoming-credits (date->str (t/plus start-date (t/days day))) 0.0)
|
||||||
debits-due-today (upcoming-debits (date->str (t/plus start-date (t/days day))) 0.0)
|
debits-due-today (upcoming-debits (date->str (t/plus start-date (t/days day))) 0.0)
|
||||||
@@ -167,7 +166,7 @@
|
|||||||
(conj acc
|
(conj acc
|
||||||
{:name (date->str today)
|
{:name (date->str today)
|
||||||
:date today
|
:date today
|
||||||
:effective-balance (+ (- effective-balance invoices-due-today )
|
:effective-balance (+ (- effective-balance invoices-due-today)
|
||||||
debits-due-today
|
debits-due-today
|
||||||
credits-yesterday)
|
credits-yesterday)
|
||||||
:credits-yesterday credits-due-today
|
:credits-yesterday credits-due-today
|
||||||
@@ -175,7 +174,7 @@
|
|||||||
:debits debits-due-today
|
:debits debits-due-today
|
||||||
:invoices (- invoices-due-today)
|
:invoices (- invoices-due-today)
|
||||||
:query-params (url/map->query {:due-range {:start (date->str today standard)
|
:query-params (url/map->query {:due-range {:start (date->str today standard)
|
||||||
:end (date->str today standard)}})})))
|
:end (date->str today standard)}})})))
|
||||||
(list {:name (date->str start-date)
|
(list {:name (date->str start-date)
|
||||||
:date start-date
|
:date start-date
|
||||||
:effective-balance effective-balance
|
:effective-balance effective-balance
|
||||||
@@ -212,7 +211,7 @@
|
|||||||
:<- [::cash-flow-table-params]
|
:<- [::cash-flow-table-params]
|
||||||
:<- [::cash-flow-data]
|
:<- [::cash-flow-data]
|
||||||
(fn [[params cash-flow-data]]
|
(fn [[params cash-flow-data]]
|
||||||
(let [ {:keys [invoices-due-soon upcoming-credits upcoming-debits]} cash-flow-data
|
(let [{:keys [invoices-due-soon upcoming-credits upcoming-debits]} cash-flow-data
|
||||||
rows (concat (map (fn [c]
|
rows (concat (map (fn [c]
|
||||||
{:date (:date c)
|
{:date (:date c)
|
||||||
:days-until (days-until (:date c))
|
:days-until (days-until (:date c))
|
||||||
@@ -233,7 +232,7 @@
|
|||||||
:name (str (:name (:vendor c)) " (" (:invoice-number c) ")")
|
:name (str (:name (:vendor c)) " (" (:invoice-number c) ")")
|
||||||
:type "Invoice"})
|
:type "Invoice"})
|
||||||
invoices-due-soon))]
|
invoices-due-soon))]
|
||||||
(assoc (grid/virtual-paginate-controls (:start params ) (:per-page params) rows)
|
(assoc (grid/virtual-paginate-controls (:start params) (:per-page params) rows)
|
||||||
:data (grid/virtual-paginate (:start params)
|
:data (grid/virtual-paginate (:start params)
|
||||||
(:per-page params)
|
(:per-page params)
|
||||||
(sort-by (comp coerce/to-date :date) rows))))))
|
(sort-by (comp coerce/to-date :date) rows))))))
|
||||||
@@ -243,19 +242,19 @@
|
|||||||
[(re-frame/inject-cofx ::inject/sub [::subs/client])]
|
[(re-frame/inject-cofx ::inject/sub [::subs/client])]
|
||||||
(fn [{:keys [db] ::subs/keys [client]} _]
|
(fn [{:keys [db] ::subs/keys [client]} _]
|
||||||
(cond->
|
(cond->
|
||||||
{:db (assoc db ::top-expense-categories nil
|
{:db (assoc db ::top-expense-categories nil
|
||||||
::cash-flow nil
|
::cash-flow nil
|
||||||
::invoice-stats nil)}
|
::invoice-stats nil)}
|
||||||
client (assoc :graphql {:token (-> db :user)
|
client (assoc :graphql {:token (-> db :user)
|
||||||
:owns-state {:single ::page}
|
:owns-state {:single ::page}
|
||||||
:query-obj {:venia/queries [[:expense_account_stats
|
:query-obj {:venia/queries [[:expense_account_stats
|
||||||
{:client-id (:id client)}
|
{:client-id (:id client)}
|
||||||
[[:account [:id :name]] :total]]
|
[[:account [:id :name]] :total]]
|
||||||
[:invoice_stats
|
[:invoice_stats
|
||||||
{:client-id (:id client)}
|
{:client-id (:id client)}
|
||||||
[:name :paid :unpaid]]
|
[:name :paid :unpaid]]
|
||||||
[:cash-flow
|
[:cash-flow
|
||||||
{:client-id (:id client)}
|
{:client-id (:id client)}
|
||||||
[:beginning-balance
|
[:beginning-balance
|
||||||
:outstanding-payments
|
:outstanding-payments
|
||||||
[:invoices-due-soon [:due :outstanding-balance [:vendor [:id :name]] :invoice-number]]
|
[:invoices-due-soon [:due :outstanding-balance [:vendor [:id :name]] :invoice-number]]
|
||||||
@@ -287,42 +286,40 @@
|
|||||||
[grid/header-cell {} "Name"]
|
[grid/header-cell {} "Name"]
|
||||||
[grid/header-cell {:class "has-text-right"} "Amount"]]]
|
[grid/header-cell {:class "has-text-right"} "Amount"]]]
|
||||||
[grid/body
|
[grid/body
|
||||||
(for [[i {:keys [date days-until type name amount] }] (map vector (range) (:data page))]
|
(for [[i {:keys [date days-until type name amount]}] (map vector (range) (:data page))]
|
||||||
^{:key i}
|
^{:key i}
|
||||||
[grid/row {}
|
[grid/row {}
|
||||||
[grid/cell {}
|
[grid/cell {}
|
||||||
(if (> days-until 0)
|
(if (> days-until 0)
|
||||||
[:span.has-text-success days-until " days"]
|
[:span.has-text-success days-until " days"]
|
||||||
[:span.has-text-danger days-until " days"])
|
[:span.has-text-danger days-until " days"])
|
||||||
[:i.is-size-7 " (" (date->str date) ")"] ]
|
[:i.is-size-7 " (" (date->str date) ")"]]
|
||||||
[grid/cell {} (if (> date 0)
|
[grid/cell {} (if (> date 0)
|
||||||
"Upcoming "
|
"Upcoming "
|
||||||
"Due ")
|
"Due ")
|
||||||
type]
|
type]
|
||||||
[grid/cell {} name]
|
[grid/cell {} name]
|
||||||
[grid/cell {:class "has-text-right"} (->$ amount)]
|
[grid/cell {:class "has-text-right"} (->$ amount)]])]]]))
|
||||||
])]]]))
|
|
||||||
|
|
||||||
(defn home-content []
|
(defn home-content []
|
||||||
(let [client-id (-> @(re-frame/subscribe [::subs/client]) :id)
|
(let [client-id (-> @(re-frame/subscribe [::subs/client]) :id)
|
||||||
chart-options @(re-frame/subscribe [::chart-options])
|
chart-options @(re-frame/subscribe [::chart-options])
|
||||||
state @(re-frame/subscribe [::status/single ::page])]
|
state @(re-frame/subscribe [::status/single ::page])]
|
||||||
^{:key client-id}
|
^{:key client-id}
|
||||||
[side-bar-layout {:side-bar [:div
|
[side-bar-layout {:side-bar [:div]
|
||||||
]
|
|
||||||
:main [:div [:h1.title "Home"]
|
:main [:div [:h1.title "Home"]
|
||||||
(if client-id
|
(if client-id
|
||||||
(if (= :loading (:state state))
|
(if (= :loading (:state state))
|
||||||
[:div.loader.is-loading.big.is-centered]
|
[:div.loader.is-loading.big.is-centered]
|
||||||
|
|
||||||
[:<>
|
[:<>
|
||||||
[:h1.title.is-4 "Top expense categories"]
|
[:h1.title.is-4 "Top expense categories"]
|
||||||
(let [expense-categories @(re-frame/subscribe [::top-expense-categories])]
|
(let [expense-categories @(re-frame/subscribe [::top-expense-categories])]
|
||||||
(make-pie-chart {:width 800 :height 500 :data (clj->js
|
(make-pie-chart {:width 800 :height 500 :data (clj->js
|
||||||
(map (fn [x] {:name (:name (:account x)) :value (:total x)}) expense-categories))}))
|
(map (fn [x] {:name (:name (:account x)) :value (:total x)}) expense-categories))}))
|
||||||
[:h1.title.is-4 "Upcoming Bills"]
|
[:h1.title.is-4 "Upcoming Bills"]
|
||||||
(make-bar-chart {:width 800 :height 500 :data (clj->js
|
(make-bar-chart {:width 800 :height 500 :data (clj->js
|
||||||
@(re-frame/subscribe [::invoice-stats]))})
|
@(re-frame/subscribe [::invoice-stats]))})
|
||||||
|
|
||||||
[:h1.title.is-4 "Cash Flow"]
|
[:h1.title.is-4 "Cash Flow"]
|
||||||
[:div.buttons.has-addons
|
[:div.buttons.has-addons
|
||||||
@@ -360,4 +357,16 @@
|
|||||||
(defn home-page []
|
(defn home-page []
|
||||||
(let [client-id (-> @(re-frame/subscribe [::subs/client]) :id)]
|
(let [client-id (-> @(re-frame/subscribe [::subs/client]) :id)]
|
||||||
(re-frame/dispatch [::mounted])
|
(re-frame/dispatch [::mounted])
|
||||||
|
^{:key client-id} [home-content]))
|
||||||
|
|
||||||
|
(defn home-page-with-vendor []
|
||||||
|
(let [client-id (-> @(re-frame/subscribe [::subs/client]) :id)
|
||||||
|
user @(re-frame/subscribe [::subs/user])]
|
||||||
|
(re-frame/dispatch [::mounted])
|
||||||
|
(when (p/can? user {:subject :vendor
|
||||||
|
:activity :create})
|
||||||
|
(re-frame/dispatch [::vendor-dialog/started {}]))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
^{:key client-id} [home-content]))
|
^{:key client-id} [home-content]))
|
||||||
|
|||||||
Reference in New Issue
Block a user