Fixing minor bugs.
This commit is contained in:
@@ -10,7 +10,8 @@
|
||||
[clojure.string :as str]
|
||||
[auto-ap.datomic.transactions :as d-transactions]
|
||||
[auto-ap.rule-matching :as rm]
|
||||
[clj-time.coerce :as coerce])
|
||||
[clj-time.coerce :as coerce]
|
||||
[clojure.tools.logging :as log])
|
||||
(:import [java.time.temporal ChronoField]))
|
||||
|
||||
|
||||
@@ -126,7 +127,7 @@
|
||||
(merge-query {:query {:in ['?description-regex]
|
||||
:where ['[?e :transaction/description-original ?do]
|
||||
'[(re-find ?description-regex ?do)]]}
|
||||
:args [(re-pattern description)]})
|
||||
:args [(rm/->pattern description)]})
|
||||
|
||||
yodlee-merchant
|
||||
(merge-query {:query {:in ['?yodlee-merchant-id]
|
||||
@@ -187,6 +188,7 @@
|
||||
|
||||
(defn test-transaction-rule [{:keys [id]} {{:keys [description note client_id bank_account_id amount_lte amount_gte dom_lte dom_gte yodlee_merchant_id]} :transaction_rule :as z} value]
|
||||
(assert-admin id)
|
||||
(log/info "HI")
|
||||
(-test-transaction-rule id #:transaction-rule {:description description
|
||||
:client (when client_id {:db/id client_id})
|
||||
:bank-account (when bank_account_id {:db/id bank_account_id})
|
||||
|
||||
@@ -10,7 +10,8 @@
|
||||
[auto-ap.datomic.transactions :as d-transactions]
|
||||
[auto-ap.datomic.clients :as d-clients]
|
||||
[auto-ap.time :as time]
|
||||
[auto-ap.datomic.transaction-rules :as tr]))
|
||||
[auto-ap.datomic.transaction-rules :as tr]
|
||||
[clojure.tools.logging :as log]))
|
||||
|
||||
(defn rule-applies? [transaction {:keys [:transaction-rule/description
|
||||
:transaction-rule/dom-gte :transaction-rule/dom-lte
|
||||
@@ -82,16 +83,19 @@
|
||||
(recur rules)))
|
||||
[])))
|
||||
|
||||
(defn ->pattern [x]
|
||||
(. java.util.regex.Pattern (compile x java.util.regex.Pattern/CASE_INSENSITIVE)))
|
||||
|
||||
(defn group-rules-by-priority [rules]
|
||||
(->> rules
|
||||
(map (fn [r] (update r :transaction-rule/description #(some-> % re-pattern))))
|
||||
(map (fn [r] (update r :transaction-rule/description #(some-> % ->pattern))))
|
||||
(group-by rule-priority)
|
||||
(sort-by first)
|
||||
(map second)))
|
||||
|
||||
(defn get-matching-rules [transaction all-rules]
|
||||
(->> all-rules
|
||||
(map (fn [r] (update r :transaction-rule/description #(some-> % re-pattern))))
|
||||
(map (fn [r] (update r :transaction-rule/description #(some-> % ->pattern))))
|
||||
(filter #(rule-applies? transaction %))))
|
||||
|
||||
(defn apply-rule [transaction rule valid-locations]
|
||||
|
||||
@@ -166,12 +166,14 @@
|
||||
[:div.column.is-1
|
||||
[:a.button {:on-click (dispatch-event [::removed-override override-key i])} [:span.icon [:span.icon-remove]]]]]))])))
|
||||
|
||||
(defn default-with-overrides [{:keys [override-key override-value-key change-event default-key data]} template]
|
||||
(defn default-with-overrides [{:keys [override-key override-value-key change-event default-key data mandatory?]} template]
|
||||
(let [clients @(re-frame/subscribe [::subs/clients])
|
||||
is-admin? @(re-frame/subscribe [::subs/is-admin?])]
|
||||
[:div
|
||||
[horizontal-field
|
||||
[:label.label "Default"]
|
||||
[:label.label [:span "Default"
|
||||
(when mandatory?
|
||||
[:span.has-text-danger " *"])]]
|
||||
[bind-field
|
||||
(template default-key nil)
|
||||
#_(assoc-in template [1 :field ] default-key)]]
|
||||
@@ -207,7 +209,8 @@
|
||||
is-admin? @(re-frame/subscribe [::subs/is-admin?])]
|
||||
[:div
|
||||
[horizontal-field
|
||||
[:label.label "Name"]
|
||||
[:label.label [:span "Name "
|
||||
[:span.has-text-danger "*"]]]
|
||||
[:div.control
|
||||
[bind-field
|
||||
[:input.input {:type "text"
|
||||
@@ -258,6 +261,7 @@
|
||||
|
||||
[:h2.subtitle "Expense Accounts"]
|
||||
[default-with-overrides {:data data :change-event change-event
|
||||
:mandatory? true
|
||||
:default-key :default-account
|
||||
:override-key :account-overrides}
|
||||
(fn [field client]
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
[auto-ap.subs :as subs]
|
||||
[auto-ap.utils :refer [replace-by]]
|
||||
[auto-ap.views.components.admin.side-bar :refer [admin-side-bar]]
|
||||
[auto-ap.views.pages.admin.accounts.side-bar :as side-bar]
|
||||
[auto-ap.views.utils :refer [dispatch-event action-cell-width]]
|
||||
[auto-ap.views.components.layouts
|
||||
:refer
|
||||
@@ -12,86 +13,118 @@
|
||||
[auto-ap.views.components.grid :as grid]
|
||||
[auto-ap.status :as status]
|
||||
[auto-ap.views.components.buttons :as buttons]
|
||||
[reagent.core :as reagent]))
|
||||
[reagent.core :as reagent]
|
||||
[clojure.string :as str]
|
||||
[vimsical.re-frame.fx.track :as track]))
|
||||
|
||||
(re-frame/reg-event-db
|
||||
::edit-completed
|
||||
(fn [db [_ edit-account]]
|
||||
(-> db
|
||||
(update :accounts replace-by :id (assoc edit-account :class "live-added")))))
|
||||
|
||||
(re-frame/reg-event-db
|
||||
::params-changed
|
||||
::table-params-changed
|
||||
(fn [db [_ p]]
|
||||
(assoc db ::params p)))
|
||||
(assoc db ::table-params p)))
|
||||
|
||||
(re-frame/reg-event-fx
|
||||
::params-change
|
||||
(fn [db [_ p]]
|
||||
{:set-uri-params p}))
|
||||
|
||||
(re-frame/reg-sub
|
||||
::table-params
|
||||
(fn [db]
|
||||
(-> db ::table-params)))
|
||||
|
||||
(re-frame/reg-sub
|
||||
::params
|
||||
(fn [db]
|
||||
(-> db ::params)))
|
||||
:<- [::table-params]
|
||||
:<- [::side-bar/filter-params]
|
||||
(fn [[table-params filter-params]]
|
||||
(cond-> {}
|
||||
(seq filter-params) (merge filter-params)
|
||||
(seq table-params) (merge table-params))))
|
||||
|
||||
|
||||
(re-frame/reg-event-fx
|
||||
::unmounted
|
||||
(fn [{:keys [db]} _]
|
||||
{:db (dissoc db ::params)}))
|
||||
{:db (dissoc db ::table-params ::side-bar/filter-params)
|
||||
::track/dispose {:id ::params}}))
|
||||
|
||||
(re-frame/reg-event-fx
|
||||
::mounted
|
||||
(fn [{:keys [db]} _]
|
||||
{::track/register {:id ::params
|
||||
:subscription [::params]
|
||||
:event-fn (fn [params] [::params-change params])}}))
|
||||
(re-frame/reg-sub
|
||||
::account-page
|
||||
:<- [::params]
|
||||
:<- [::subs/all-accounts]
|
||||
(fn [[params all-accounts]]
|
||||
(let [matching-accounts (cond->> all-accounts
|
||||
(:name-like params) (filter #(str/includes? (str/lower-case (or (:name %) ""))
|
||||
(str/lower-case (:name-like params))))
|
||||
(not-empty (:code-like params)) (filter #(str/starts-with? (str (or (:numeric-code %) ""))
|
||||
(str/lower-case (:code-like params)))))]
|
||||
(assoc (grid/virtual-paginate-controls (:start params ) matching-accounts)
|
||||
:data (grid/virtual-paginate (:start params)
|
||||
|
||||
(sort-by :numeric-code matching-accounts))))))
|
||||
|
||||
(defn accounts-table [{:keys [accounts]}]
|
||||
(let [status @(re-frame/subscribe [::status/single ::page])
|
||||
opc (fn [p]
|
||||
(re-frame/dispatch [::params-changed p]))
|
||||
(re-frame/dispatch [::table-params-changed p]))
|
||||
params @(re-frame/subscribe [::params])]
|
||||
|
||||
[:div
|
||||
(for [[account-set full-accounts] (group-by :account-set accounts)
|
||||
:let [full-accounts (sort-by :numeric-code full-accounts)
|
||||
accounts (grid/virtual-paginate (:start params 0) full-accounts )]]
|
||||
^{:key (or account-set "blank")}
|
||||
[:div
|
||||
[:h2.title.is-4 account-set]
|
||||
[grid/grid {:status status
|
||||
:on-params-change opc
|
||||
:params params
|
||||
:column-count 5}
|
||||
[grid/controls (grid/virtual-paginate-controls (:start params) full-accounts)]
|
||||
[grid/table {:fullwidth true}
|
||||
[grid/header
|
||||
[grid/row {}
|
||||
[grid/header-cell {} "Code"]
|
||||
[grid/header-cell {} "Name"]
|
||||
[grid/header-cell {} "Type"]
|
||||
[grid/header-cell {} "Location"]
|
||||
[grid/header-cell {:style {:width (action-cell-width 1)}} ]]]
|
||||
[grid/body
|
||||
(for [{:keys [id numeric-code name type location class] :as account} accounts]
|
||||
^{:key id}
|
||||
[grid/row {:class (:class account)}
|
||||
[grid/cell {} numeric-code]
|
||||
[grid/cell {} name]
|
||||
[grid/cell {} type]
|
||||
[grid/cell {} location]
|
||||
[grid/cell {}
|
||||
[buttons/fa-icon {:event [::account-form/editing account [::edit-completed]]
|
||||
:icon "fa-pencil"}]]])]]]])]))
|
||||
[:div
|
||||
[grid/grid {:status status
|
||||
:on-params-change opc
|
||||
:params params
|
||||
:column-count 5}
|
||||
[grid/controls accounts]
|
||||
[grid/table {:fullwidth true}
|
||||
[grid/header
|
||||
[grid/row {}
|
||||
[grid/header-cell {} "Code"]
|
||||
[grid/header-cell {} "Name"]
|
||||
[grid/header-cell {} "Type"]
|
||||
[grid/header-cell {} "Location"]
|
||||
[grid/header-cell {:style {:width (action-cell-width 1)}} ]]]
|
||||
[grid/body
|
||||
(for [{:keys [id numeric-code name type location class] :as account} (:data accounts)]
|
||||
^{:key id}
|
||||
[grid/row {:class (:class account)}
|
||||
[grid/cell {} numeric-code]
|
||||
[grid/cell {} name]
|
||||
[grid/cell {} type]
|
||||
[grid/cell {} location]
|
||||
[grid/cell {}
|
||||
[buttons/fa-icon {:event [::account-form/editing account [::edit-completed]]
|
||||
:icon "fa-pencil"}]]])]]]]))
|
||||
|
||||
(defn admin-accounts-content []
|
||||
[:div
|
||||
(let [accounts @(re-frame/subscribe [::subs/all-accounts])]
|
||||
[:div
|
||||
[:h1.title "Accounts"]
|
||||
[:div.is-pulled-right
|
||||
[:a.button.is-success {:on-click (dispatch-event [::account-form/editing
|
||||
{:type :asset
|
||||
:account-set "default"}
|
||||
[::edit-completed]])} "New Account"]]
|
||||
[accounts-table {:accounts accounts}]])])
|
||||
[:h1.title "Accounts"]
|
||||
[:div.is-pulled-right
|
||||
[:a.button.is-success {:on-click (dispatch-event [::account-form/editing
|
||||
{:type :asset
|
||||
:account-set "default"}
|
||||
[::edit-completed]])} "New Account"]]
|
||||
[accounts-table {:accounts @(re-frame/subscribe [::account-page])}]])
|
||||
|
||||
(defn admin-accounts-page []
|
||||
(reagent/create-class
|
||||
{:display-name "accounts-page"
|
||||
:component-will-unmount #(re-frame/dispatch [::unmounted])
|
||||
:component-did-mount #(re-frame/dispatch [::mounted])
|
||||
:reagent-render
|
||||
(fn []
|
||||
(let [{:keys [active?]} @(re-frame/subscribe [::forms/form ::account-form/form])]
|
||||
[side-bar-layout {:side-bar [admin-side-bar {}]
|
||||
[side-bar-layout {:side-bar [admin-side-bar {}
|
||||
[side-bar/accounts-side-bar]]
|
||||
:main [admin-accounts-content]
|
||||
:right-side-bar [appearing-side-bar {:visible? active?} [account-form/form ]]}]))}))
|
||||
|
||||
@@ -233,7 +233,8 @@
|
||||
(form-inline (assoc params :title "New Invoice")
|
||||
[:<>
|
||||
(when-not @(re-frame/subscribe [::subs/client])
|
||||
(field "Client"
|
||||
(field [:span "Client"
|
||||
[:span.has-text-danger " *"]]
|
||||
[typeahead-entity {:matches @(re-frame/subscribe [::subs/clients])
|
||||
:match->text :name
|
||||
:type "typeahead"
|
||||
@@ -242,7 +243,8 @@
|
||||
:disabled exists?
|
||||
:spec ::invoice/client}]))
|
||||
|
||||
(field "Vendor"
|
||||
(field [:span "Vendor"
|
||||
[:span.has-text-danger " *"]]
|
||||
[typeahead-entity {:matches @(re-frame/subscribe [::subs/vendors])
|
||||
:match->text :name
|
||||
:type "typeahead"
|
||||
@@ -250,7 +252,8 @@
|
||||
:auto-focus (if @(re-frame/subscribe [::subs/client]) true false)
|
||||
:field [:vendor]}])
|
||||
|
||||
(field "Date"
|
||||
(field [:span "Date"
|
||||
[:span.has-text-danger " *"]]
|
||||
[date-picker {:class-name "input"
|
||||
:class "input"
|
||||
:format-week-number (fn [] "")
|
||||
@@ -282,13 +285,15 @@
|
||||
:spec ::invoice/automatically-paid-when-due}])
|
||||
" Mark as paid on due date"]]
|
||||
|
||||
(field "Invoice #"
|
||||
(field [:span "Invoice #"
|
||||
[:span.has-text-danger " *"]]
|
||||
[:input.input {:type "text"
|
||||
:field [:invoice-number]
|
||||
:spec ::invoice/invoice-number}])
|
||||
|
||||
|
||||
(field "Total"
|
||||
(field [:span "Total"
|
||||
[:span.has-text-danger " *"]]
|
||||
[money-field {:type "money"
|
||||
:field [:total]
|
||||
:disabled (if can-change-amount? "" "disabled")
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
[goog.string :as gstring]
|
||||
[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 pretty dispatch-event local-now ->% ->$ str->date with-user]]
|
||||
[auto-ap.views.utils :refer [date->str date-picker bind-field standard pretty dispatch-event local-today ->% ->$ str->date with-user]]
|
||||
[cljs-time.core :as t]
|
||||
[re-frame.core :as re-frame]
|
||||
[auto-ap.status :as status]))
|
||||
@@ -199,6 +199,7 @@
|
||||
(re-frame/reg-event-fx
|
||||
::date-picked
|
||||
(fn [cofx [_ [_ period which] date]]
|
||||
(println date (str->date date standard))
|
||||
{:dispatch [::range-selected (assoc-in @(re-frame/subscribe [::periods]) [period which] (str->date date standard)) nil]}))
|
||||
|
||||
(re-frame/reg-event-fx
|
||||
@@ -493,8 +494,8 @@
|
||||
{:class (when (= (:selected params) "13 periods") "is-active")
|
||||
:on-click (dispatch-event
|
||||
[::range-selected
|
||||
(let [this-month (t/local-date (t/year (local-now))
|
||||
(t/month (local-now))
|
||||
(let [this-month (t/local-date (t/year (local-today))
|
||||
(t/month (local-today))
|
||||
1)]
|
||||
(into
|
||||
[[this-month (t/minus (t/plus this-month (t/months 1)) (t/days 1))]]
|
||||
@@ -509,7 +510,7 @@
|
||||
[:a.button
|
||||
{:class (when (= (:selected params) "Last week") "is-active")
|
||||
:on-click (dispatch-event
|
||||
(let [last-sunday (loop [current (local-now)]
|
||||
(let [last-sunday (loop [current (local-today)]
|
||||
(if (= 7 (t/day-of-week current))
|
||||
current
|
||||
(recur (t/minus current (t/period :days 1)))))]
|
||||
@@ -521,23 +522,23 @@
|
||||
[:a.button
|
||||
{:class (when (= (:selected params) "Week to date") "is-active")
|
||||
:on-click (dispatch-event [::range-selected
|
||||
(and-last-year [(loop [current (local-now)]
|
||||
(and-last-year [(loop [current (local-today)]
|
||||
(if (= 1 (t/day-of-week current))
|
||||
current
|
||||
(recur (t/minus current (t/period :days 1)))))
|
||||
(local-now)])
|
||||
(local-today)])
|
||||
"Week to date"])}
|
||||
"Week to date"]]
|
||||
[:div.control
|
||||
[:a.button
|
||||
{:class (when (= (:selected params) "Last Month") "is-active")
|
||||
:on-click (dispatch-event [::range-selected
|
||||
(and-last-year [(t/minus (t/local-date (t/year (local-now))
|
||||
(t/month (local-now))
|
||||
(and-last-year [(t/minus (t/local-date (t/year (local-today))
|
||||
(t/month (local-today))
|
||||
1)
|
||||
(t/period :months 1))
|
||||
(t/minus (t/local-date (t/year (local-now))
|
||||
(t/month (local-now))
|
||||
(t/minus (t/local-date (t/year (local-today))
|
||||
(t/month (local-today))
|
||||
1)
|
||||
(t/period :days 1))])
|
||||
"Last Month"])}
|
||||
@@ -546,27 +547,27 @@
|
||||
[:a.button
|
||||
{:class (when (= (:selected params) "Month to date") "is-active")
|
||||
:on-click (dispatch-event [::range-selected
|
||||
(and-last-year [(t/local-date (t/year (local-now))
|
||||
(t/month (local-now))
|
||||
(and-last-year [(t/local-date (t/year (local-today))
|
||||
(t/month (local-today))
|
||||
1)
|
||||
(local-now)])
|
||||
(local-today)])
|
||||
"Month to date"])}
|
||||
"Month to date"]]
|
||||
[:div.control
|
||||
[:a.button
|
||||
{:class (when (= (:selected params) "Year to date") "is-active")
|
||||
:on-click (dispatch-event [::range-selected
|
||||
(and-last-year [(t/local-date (t/year (local-now)) 1 1)
|
||||
(local-now)])
|
||||
(and-last-year [(t/local-date (t/year (local-today)) 1 1)
|
||||
(local-today)])
|
||||
"Year to date"])}
|
||||
"Year to date"]]
|
||||
[:div.control
|
||||
[:a.button
|
||||
{:class (when (= (:selected params) "Full year") "is-active")
|
||||
:on-click (dispatch-event [::range-selected
|
||||
(and-last-year [(t/plus (t/minus (local-now) (t/period :years 1))
|
||||
(and-last-year [(t/plus (t/minus (local-today) (t/period :years 1))
|
||||
(t/period :days 1))
|
||||
(local-now)])
|
||||
(local-today)])
|
||||
"Full year"])}
|
||||
"Full year"]]]]
|
||||
(for [[_ i] (map vector periods (range))]
|
||||
@@ -635,7 +636,7 @@
|
||||
^{:key location}
|
||||
[location-rows location]
|
||||
)]]]])])))
|
||||
{:component-will-mount #(do (re-frame/dispatch-sync [::range-selected (and-last-year [(t/minus (local-now) (t/period :years 1)) (local-now)]) nil])) }))
|
||||
{:component-will-mount #(do (re-frame/dispatch-sync [::range-selected (and-last-year [(t/minus (local-today) (t/period :years 1)) (local-today)]) nil])) }))
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -90,6 +90,7 @@
|
||||
|
||||
(defn dispatch-date-change [event]
|
||||
(fn [e g]
|
||||
(println e (c/from-date e) (time/from-default-time-zone (c/from-date e)) (date->str (time/from-default-time-zone (c/from-date e)) standard))
|
||||
(re-frame/dispatch (conj event
|
||||
(if (str/blank? e)
|
||||
e
|
||||
@@ -283,6 +284,7 @@
|
||||
|
||||
:else
|
||||
selected )
|
||||
|
||||
keys (assoc keys
|
||||
:on-change (dispatch-date-change (conj event field))
|
||||
:selected selected
|
||||
@@ -411,6 +413,9 @@
|
||||
(defn local-now []
|
||||
(t/to-default-time-zone (t/now)))
|
||||
|
||||
(defn local-today []
|
||||
(t/at-midnight (t/to-default-time-zone (t/now))))
|
||||
|
||||
(def with-user
|
||||
(re-frame/->interceptor
|
||||
:id :with-user
|
||||
|
||||
Reference in New Issue
Block a user