Allows making rules by client group

This commit is contained in:
2024-02-08 15:56:46 -08:00
parent a5e6b0549d
commit c290c34ec7
8 changed files with 75 additions and 23 deletions

View File

@@ -148,7 +148,7 @@
:uberjar :uberjar
{ {
:java-cmd "/usr/lib/jvm/java-11-openjdk/bin/java" ;;:java-cmd "/usr/lib/jvm/java-11-openjdk/bin/java"
:prep-tasks ["fig:min" ] :prep-tasks ["fig:min" ]
:aot [auto-ap.server auto-ap.time clj-time.core clj-time.coerce clj-time.format clojure.tools.logging.impl ] :aot [auto-ap.server auto-ap.time clj-time.core clj-time.coerce clj-time.format clojure.tools.logging.impl ]
:dependencies [[com.bhauman/figwheel-main "0.2.18" :exclusions [org.clojure/clojurescript :dependencies [[com.bhauman/figwheel-main "0.2.18" :exclusions [org.clojure/clojurescript

View File

@@ -1334,6 +1334,10 @@
:db/cardinality #:db{:ident :db.cardinality/one}, :db/cardinality #:db{:ident :db.cardinality/one},
:db/doc "The specific client this rule is for", :db/doc "The specific client this rule is for",
:db/ident :transaction-rule/client} :db/ident :transaction-rule/client}
{:db/valueType #:db{:ident :db.type/string},
:db/cardinality #:db{:ident :db.cardinality/one},
:db/doc "The specific client group this rule is for",
:db/ident :transaction-rule/client-group}
{:db/valueType #:db{:ident :db.type/ref}, {:db/valueType #:db{:ident :db.type/ref},
:db/cardinality #:db{:ident :db.cardinality/one}, :db/cardinality #:db{:ident :db.cardinality/one},
:db/doc "The specific bank account this rule is for", :db/doc "The specific bank account this rule is for",

View File

@@ -22,6 +22,7 @@
:transaction-rule/amount-gte :transaction-rule/amount-gte
:transaction-rule/dom-lte :transaction-rule/dom-lte
:transaction-rule/dom-gte :transaction-rule/dom-gte
:transaction-rule/client-group
{:transaction-rule/client [:client/name :db/id :client/code]} {:transaction-rule/client [:client/name :db/id :client/code]}
{:transaction-rule/bank-account [:db/id :bank-account/name]} {:transaction-rule/bank-account [:db/id :bank-account/name]}
{:transaction-rule/yodlee-merchant [:db/id :yodlee-merchant/name :yodlee-merchant/yodlee-id]} {:transaction-rule/yodlee-merchant [:db/id :yodlee-merchant/name :yodlee-merchant/yodlee-id]}
@@ -117,7 +118,10 @@
[?e :transaction-rule/transaction-approval-status] [?e :transaction-rule/transaction-approval-status]
(or-join [?e ?c] (or-join [?e ?c]
[?e :transaction-rule/client ?c] [?e :transaction-rule/client ?c]
(not [?e :transaction-rule/client]))] (and [?c :client/groups ?g]
[?e :transaction-rule/client-group ?g])
(and (not [?e :transaction-rule/client])
(not [?e :transaction-rule/client-group])))]
(dc/db conn) (dc/db conn)
client-id client-id
default-read))) default-read)))

View File

@@ -231,7 +231,7 @@
(defn get-by-id [id] (defn get-by-id [id]
(-> (->
(dc/pull (dc/db conn) (dc/pull (dc/db conn)
'[* {:transaction/client [:client/name :db/id :client/code :client/locations] '[* {:transaction/client [:client/name :db/id :client/code :client/locations :client/groups]
:transaction/approval-status [:db/ident :db/id] :transaction/approval-status [:db/ident :db/id]
:transaction/bank-account [:bank-account/name :bank-account/code :bank-account/yodlee-account-id :db/id :bank-account/locations :bank-account/current-balance] :transaction/bank-account [:bank-account/name :bank-account/code :bank-account/yodlee-account-id :db/id :bank-account/locations :bank-account/current-balance]
:transaction/vendor [:db/id :vendor/name] :transaction/vendor [:db/id :vendor/name]

View File

@@ -34,7 +34,7 @@
] ]
(mu/log ::counted (mu/log ::counted
:count (count all-rules)) :count (count all-rules))
(map ->graphql (rm/get-matching-rules transaction all-rules))) (doto (map ->graphql (rm/get-matching-rules transaction all-rules)) (#(println (count %)))))
nil)) nil))
(defn transaction-rule-account->entity [{:keys [id account_id percentage location]}] (defn transaction-rule-account->entity [{:keys [id account_id percentage location]}]

View File

@@ -1,8 +1,10 @@
(ns auto-ap.rule-matching (ns auto-ap.rule-matching
(:require [iol-ion.tx :refer [random-tempid]] (:require [auto-ap.logging :as alog]
[iol-ion.query :refer [->pattern]])) [iol-ion.query :refer [->pattern]]
[iol-ion.tx :refer [random-tempid]]))
(defn rule-applies? [transaction {:keys [:transaction-rule/description (defn rule-applies? [transaction {:keys [:transaction-rule/description
:transaction-rule/client-group
:transaction-rule/dom-gte :transaction-rule/dom-lte :transaction-rule/dom-gte :transaction-rule/dom-lte
:transaction-rule/amount-gte :transaction-rule/amount-lte :transaction-rule/amount-gte :transaction-rule/amount-lte
:transaction-rule/client :transaction-rule/bank-account :transaction-rule/client :transaction-rule/bank-account
@@ -23,13 +25,18 @@
(<= transaction-dom dom-lte) (<= transaction-dom dom-lte)
true) true)
(if amount-gte (if amount-gte
(>= (:transaction/amount transaction) amount-gte) (>= (:transaction/amount transaction) amount-gte)
true) true)
(if amount-lte (if amount-lte
(<= (:transaction/amount transaction) amount-lte) (<= (:transaction/amount transaction) amount-lte)
true) true)
(if client-group
(do
(println "CHECKING HERE" client-group)
((set (-> transaction :transaction/client :client/groups)) client-group))
true)
(if client (if client
(or (or
(= (:transaction/client transaction) (= (:transaction/client transaction)
(:db/id client)) (:db/id client))
(= (:db/id (:transaction/client transaction)) (= (:db/id (:transaction/client transaction))
@@ -40,7 +47,7 @@
(:yodlee-merchant/yodlee-id yodlee-merchant)) (:yodlee-merchant/yodlee-id yodlee-merchant))
true) true)
(if bank-account (if bank-account
(or (or
(= (:db/id (:transaction/bank-account transaction)) (= (:db/id (:transaction/bank-account transaction))
(:db/id bank-account)) (:db/id bank-account))
(= (:transaction/bank-account transaction) (= (:transaction/bank-account transaction)
@@ -51,12 +58,13 @@
(or (or
(->> [[:transaction-rule/bank-account 0] (->> [[:transaction-rule/bank-account 0]
[:transaction-rule/client 1] [:transaction-rule/client 1]
[:transaction-rule/dom-lte 2] [:transaction-rule/client-group 2]
[:transaction-rule/dom-gte 2] [:transaction-rule/dom-lte 3]
[:transaction-rule/amount-lte 3] [:transaction-rule/dom-gte 4]
[:transaction-rule/amount-gte 3] [:transaction-rule/amount-lte 4]
[:transaction-rule/description 4] [:transaction-rule/amount-gte 4]
[:transaction-rule/yodlee-merchant 5]] [:transaction-rule/description 5]
[:transaction-rule/yodlee-merchant 6]]
(filter (fn [[key]] (filter (fn [[key]]
(get rule key))) (get rule key)))
(map second) (map second)
@@ -83,8 +91,8 @@
(defn get-matching-rules [transaction all-rules] (defn get-matching-rules [transaction all-rules]
(->> all-rules (->> all-rules
(map (fn [r] (update r :transaction-rule/description #(some-> % ->pattern)))) (map (fn [r] (update r :transaction-rule/description #(some-> % ->pattern))))
(filter #(rule-applies? transaction %)))) (filter #(rule-applies? transaction %))))
(defn spread-cents [cents n] (defn spread-cents [cents n]
(let [default-spread (for [_ (range n)] (let [default-spread (for [_ (range n)]

View File

@@ -33,7 +33,6 @@
(println "LOADING SERVER") (println "LOADING SERVER")
(defn add-shutdown-hook! [^Runnable f] (defn add-shutdown-hook! [^Runnable f]
(.addShutdownHook (Runtime/getRuntime) (.addShutdownHook (Runtime/getRuntime)
(Thread. f))) (Thread. f)))
@@ -157,7 +156,9 @@
:else :else
(do (do
(add-shutdown-hook! shutdown-mount) (add-shutdown-hook! shutdown-mount)
(println "HI?")
(start-server :port 9000 :bind "0.0.0.0" #_#_:handler (cider-nrepl-handler)) (start-server :port 9000 :bind "0.0.0.0" #_#_:handler (cider-nrepl-handler))
(mount/start) (println "HI 2?")
(mount/start (mount/except (mount/only #{#'user/jetty})))
#_(alter-var-root #'nrepl.middleware.print/*print-fn* (constantly clojure.pprint/pprint)))))) #_(alter-var-root #'nrepl.middleware.print/*print-fn* (constantly clojure.pprint/pprint))))))

View File

@@ -70,12 +70,20 @@
:class "hot-filter" :class "hot-filter"
:value (:description (:parsed-query-params request)) :value (:description (:parsed-query-params request))
:placeholder "LOWES" :placeholder "LOWES"
:size :small}))
(com/field {:label "Client group"}
(com/text-input {:name "client-group"
:id "client-group"
:class "hot-filter"
:value (:client-group (:parsed-query-params request))
:placeholder "NTG"
:size :small}))]]) :size :small}))]])
(def default-read '[:db/id (def default-read '[:db/id
:transaction-rule/description :transaction-rule/description
:transaction-rule/note :transaction-rule/note
:transaction-rule/amount-lte :transaction-rule/amount-lte
:transaction-rule/client-group
:transaction-rule/amount-gte :transaction-rule/amount-gte
:transaction-rule/dom-lte :transaction-rule/dom-lte
:transaction-rule/dom-gte :transaction-rule/dom-gte
@@ -139,6 +147,11 @@
'[(clojure.string/includes? ?d2 ?description)]]} '[(clojure.string/includes? ?d2 ?description)]]}
:args [(clojure.string/lower-case (:description query-params))]}) :args [(clojure.string/lower-case (:description query-params))]})
(not (str/blank? (:client-group query-params)))
(merge-query {:query {:in ['?client-group]
:where ['[?e :transaction-rule/client-group ?client-group] ]}
:args [(clojure.string/upper-case (:client-group query-params))]})
true true
(merge-query {:query {:find ['?e] (merge-query {:query {:find ['?e]
:where ['[?e :transaction-rule/transaction-approval-status]]}}))] :where ['[?e :transaction-rule/transaction-approval-status]]}}))]
@@ -198,7 +211,8 @@
:headers [{:key "client" :headers [{:key "client"
:name "Client" :name "Client"
:sort-key "client" :sort-key "client"
:render #(-> % :transaction-rule/client :client/name)} :render #(or (-> % :transaction-rule/client :client/name)
(some->> % :transaction-rule/client-group (str "group ") (com/pill {:color :primary})))}
{:key "bank-account" {:key "bank-account"
:name "Bank account" :name "Bank account"
:sort-key "bank-account" :sort-key "bank-account"
@@ -281,7 +295,7 @@
:db/id :db/id
[:transaction/date :xform clj-time.coerce/from-date]]) [:transaction/date :xform clj-time.coerce/from-date]])
(defn transactions-matching-rule [{{:transaction-rule/keys [description client bank-account amount-lte amount-gte dom-lte dom-gte]} (defn transactions-matching-rule [{{:transaction-rule/keys [description client bank-account amount-lte amount-gte dom-lte dom-gte client-group]}
:entity :entity
clients :clients clients :clients
only-uncoded? :only-uncoded?}] only-uncoded? :only-uncoded?}]
@@ -297,7 +311,11 @@
(merge-query {:query {:in ['?descr] (merge-query {:query {:in ['?descr]
:where ['[(iol-ion.query/->pattern ?descr) ?description-regex]]} :where ['[(iol-ion.query/->pattern ?descr) ?description-regex]]}
:args [description]}) :args [description]})
client-group
(merge-query {:query {:in ['?client-group]
:where ['[?e :transaction/client ?client-group-client]
'[?client-group-client :client/groups ?client-group]]}
:args [client-group]})
valid-clients valid-clients
(merge-query {:query {:in ['[?xx ...]] (merge-query {:query {:in ['[?xx ...]]
:where ['[?e :transaction/client ?xx]]} :where ['[?e :transaction/client ?xx]]}
@@ -553,6 +571,7 @@
[:map [:map
[:db/id {:optional true} [:maybe entity-id]] [:db/id {:optional true} [:maybe entity-id]]
[:transaction-rule/client {:optional true} [:maybe entity-id]] [:transaction-rule/client {:optional true} [:maybe entity-id]]
[:transaction-rule/client-group {:optional true} [:maybe :string]]
[:transaction-rule/description [:and regex [:transaction-rule/description [:and regex
[:string {:min 3}]]] [:string {:min 3}]]]
[:transaction-rule/bank-account [:maybe entity-id]] [:transaction-rule/bank-account [:maybe entity-id]]
@@ -652,6 +671,7 @@
:class "w-96" :class "w-96"
:value (fc/field-value)}))) :value (fc/field-value)})))
[:div.filters {:x-data (hx/json {:clientFilter (boolean (fc/field-value (:transaction-rule/client fc/*current*))) [:div.filters {:x-data (hx/json {:clientFilter (boolean (fc/field-value (:transaction-rule/client fc/*current*)))
:clientGroupFilter (boolean (fc/field-value (:transaction-rule/client-group fc/*current*)))
:bankAccountFilter (boolean (fc/field-value (:transaction-rule/bank-account fc/*current*))) :bankAccountFilter (boolean (fc/field-value (:transaction-rule/bank-account fc/*current*)))
:amountFilter (boolean (or (fc/field-value (:transaction-rule/amount-gte fc/*current*)) :amountFilter (boolean (or (fc/field-value (:transaction-rule/amount-gte fc/*current*))
(fc/field-value (:transaction-rule/amount-lte fc/*current*)))) (fc/field-value (:transaction-rule/amount-lte fc/*current*))))
@@ -661,6 +681,8 @@
[:div.flex.gap-2.mb-2 [:div.flex.gap-2.mb-2
(com/a-button {"@click" "clientFilter=true" (com/a-button {"@click" "clientFilter=true"
"x-show" "!clientFilter"} "Filter client") "x-show" "!clientFilter"} "Filter client")
(com/a-button {"@click" "clientGroupFilter=true"
"x-show" "!clientGroupFilter"} "Filter client group")
(com/a-button {"@click" "bankAccountFilter=true" (com/a-button {"@click" "bankAccountFilter=true"
"x-show" "clientFilter && !bankAccountFilter"} "Filter bank account") "x-show" "clientFilter && !bankAccountFilter"} "Filter bank account")
(com/a-button {"@click" "amountFilter=true" (com/a-button {"@click" "amountFilter=true"
@@ -683,7 +705,19 @@
:x-model "clientId" :x-model "clientId"
:value (fc/field-value) :value (fc/field-value)
:content-fn (fn [c] (pull-attr (dc/db conn) :client/name c))})])) :content-fn (fn [c] (pull-attr (dc/db conn) :client/name c))})]))
(fc/with-field :transaction-rule/client-group
(com/validated-field
(-> {:label "Client Group"
:errors (fc/field-errors)
:x-show "clientGroupFilter"}
(hx/alpine-appear))
[:div.w-96
(com/text-input {:name (fc/field-name)
:error? (fc/error?)
:class "w-24"
:placeholder "NTG"
:value (fc/field-value)})]))
(fc/with-field :transaction-rule/bank-account (fc/with-field :transaction-rule/bank-account
(com/validated-field (com/validated-field
(-> {:label "Bank Account" (-> {:label "Bank Account"
@@ -846,6 +880,7 @@
(let [transaction-rule (:snapshot multi-form-state) (let [transaction-rule (:snapshot multi-form-state)
_ (validate-transaction-rule transaction-rule) _ (validate-transaction-rule transaction-rule)
entity (cond-> transaction-rule entity (cond-> transaction-rule
(:transaction-rule/client-group transaction-rule) (update :transaction-rule/client-group str/upper-case)
(= :post request-method) (assoc :db/id "new") (= :post request-method) (assoc :db/id "new")
true (assoc :transaction-rule/note (entity->note transaction-rule))) true (assoc :transaction-rule/note (entity->note transaction-rule)))
{:keys [tempids]} (audit-transact [[:upsert-entity entity]] {:keys [tempids]} (audit-transact [[:upsert-entity entity]]