Adds ability to find expected deposits and link them
This commit is contained in:
@@ -32,6 +32,11 @@
|
||||
:where ['[?e :expected-deposit/client ?xx]]}
|
||||
:args [(set (map :db/id (limited-clients (:id args))))]})
|
||||
|
||||
(:exact-match-id args)
|
||||
(merge-query {:query {:in ['?e]
|
||||
:where []}
|
||||
:args [(:exact-match-id args)]})
|
||||
|
||||
(:client-id args)
|
||||
(merge-query {:query {:in ['?client-id]
|
||||
:where ['[?e :expected-deposit/client ?client-id]]}
|
||||
|
||||
@@ -195,10 +195,15 @@
|
||||
:add-sales-date {:txes [[{:db/ident :expected-deposit/sales-date
|
||||
:db/doc "The date of sales the deposit was for"
|
||||
:db/valueType :db.type/instant
|
||||
:db/cardinality :db.cardinality/one}]]}})
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
:db/cardinality :db.cardinality/one}]]}
|
||||
:add-expected-deposit-status {:txes [[{:db/ident :expected-deposit/status
|
||||
:db/doc "Whether the deposit has been cleared"
|
||||
:db/valueType :db.type/ref
|
||||
:db/cardinality :db.cardinality/one}
|
||||
{:db/ident :expected-deposit-status/pending}
|
||||
{:db/ident :expected-deposit-status/cleared}
|
||||
{:db/ident :transaction/expected-deposit
|
||||
:db/doc "If this transaction is a deposit, the deposit that we anticipated"
|
||||
:db/valueType :db.type/ref
|
||||
:db/cardinality :db.cardinality/one}]]}})
|
||||
|
||||
|
||||
@@ -158,6 +158,7 @@
|
||||
:transaction/vendor [:db/id :vendor/name]
|
||||
:transaction/matched-rule [:db/id :transaction-rule/note]
|
||||
:transaction/payment [:db/id :payment/date]
|
||||
:transaction/expected-deposit [:db/id :expected-deposit/date]
|
||||
:transaction/accounts [:transaction-account/amount
|
||||
:db/id
|
||||
:transaction-account/location
|
||||
@@ -167,9 +168,10 @@
|
||||
(map #(update % :transaction/date c/from-date))
|
||||
(map #(update % :transaction/post-date c/from-date))
|
||||
(map (fn [transaction]
|
||||
(if (:transaction/payment transaction)
|
||||
(update-in transaction [:transaction/payment :payment/date] c/from-date)
|
||||
transaction)))
|
||||
(cond-> transaction
|
||||
(:transaction/payment transaction) (update-in [:transaction/payment :payment/date] c/from-date)
|
||||
(:transaction/expected-deposit transaction) (update-in [:transaction/expected-deposit :expected-deposit/date] c/from-date))
|
||||
))
|
||||
(map #(dissoc % :transaction/id))
|
||||
(group-by :db/id))]
|
||||
|
||||
|
||||
@@ -339,6 +339,7 @@
|
||||
:client {:type :client}
|
||||
:accounts {:type '(list :invoices_expense_accounts)}
|
||||
:payment {:type :payment}
|
||||
:expected_deposit {:type :expected_deposit}
|
||||
:vendor {:type :vendor}
|
||||
:bank_account {:type :bank_account}
|
||||
:date {:type 'String}
|
||||
@@ -651,6 +652,7 @@
|
||||
|
||||
:expected_deposit_page {:type :expected_deposit_page
|
||||
:args {:client_id {:type :id}
|
||||
:exact_match_id {:type :id}
|
||||
:date_range {:type :date_range}
|
||||
:total_lte {:type :money}
|
||||
:total_gte {:type :money}
|
||||
|
||||
@@ -155,9 +155,24 @@
|
||||
nil))
|
||||
nil))
|
||||
|
||||
(defn find-expected-deposit [client-id amount date]
|
||||
(when date
|
||||
(-> (d/q
|
||||
'[:find ?ed
|
||||
:in $ ?c ?a ?d-start
|
||||
:where
|
||||
[?ed :expected-deposit/client ?c]
|
||||
(not [?ed :expected-deposit/status :expected-deposit-status/cleared])
|
||||
[?ed :expected-deposit/date ?d]
|
||||
[(>= ?d ?d-start)]
|
||||
[?ed :expected-deposit/total ?a2]
|
||||
[(auto-ap.utils/dollars= ?a2 ?a)]
|
||||
]
|
||||
(d/db conn) client-id amount (coerce/to-date (t/plus date (t/days -10))))
|
||||
first
|
||||
first)))
|
||||
|
||||
(defn transactions->txs [transactions transaction->bank-account apply-rules existing]
|
||||
(log/info transactions)
|
||||
|
||||
(into []
|
||||
|
||||
(for [transaction transactions
|
||||
@@ -190,13 +205,15 @@
|
||||
(= "POSTED" status)
|
||||
|
||||
(or (not (:start-date bank-account))
|
||||
(t/after? date (:start-date bank-account)))
|
||||
)]
|
||||
(t/after? date (:start-date bank-account))))]
|
||||
(let [existing-check (transaction->existing-payment transaction check-number client-id bank-account-id amount id)
|
||||
autopay-invoices-matches (when-not existing-check
|
||||
(match-transaction-to-unfulfilled-autopayments amount client-id ))
|
||||
unpaid-invoices-matches (when-not existing-check
|
||||
(match-transaction-to-unpaid-invoices amount client-id ))]
|
||||
(match-transaction-to-unpaid-invoices amount client-id ))
|
||||
expected-deposit (when (and (> amount 0.0)
|
||||
(not existing-check))
|
||||
(find-expected-deposit client-id amount date))]
|
||||
(cond->
|
||||
[#:transaction
|
||||
{:post-date (coerce/to-date (time/parse post-date "YYYY-MM-dd"))
|
||||
@@ -225,10 +242,13 @@
|
||||
;; temporarily removed to automatically match autopaid invoices
|
||||
#_(and (not existing-check)
|
||||
(seq autopay-invoices-matches)) #_(add-new-payment autopay-invoices-matches bank-account-id client-id)
|
||||
expected-deposit (update 0 #(assoc % :transaction/expected-deposit {:db/id expected-deposit
|
||||
:expected-deposit/status :expected-deposit-status/cleared}))
|
||||
|
||||
|
||||
(and (not (seq autopay-invoices-matches))
|
||||
(not (seq unpaid-invoices-matches))) (update 0 #(apply-rules % valid-locations))
|
||||
(not (seq unpaid-invoices-matches))
|
||||
(not expected-deposit)) (update 0 #(apply-rules % valid-locations))
|
||||
true (update 0 remove-nils))))))
|
||||
|
||||
|
||||
|
||||
109
src/clj/user.clj
109
src/clj/user.clj
@@ -635,4 +635,113 @@
|
||||
|
||||
(auto-ap.square.core/upsert-settlements client-code)))
|
||||
|
||||
(defn upsert-invoice-amounts [tsv]
|
||||
(let [data (with-open [reader (io/reader (char-array tsv))]
|
||||
(doall (csv/read-csv reader :separator \tab)))
|
||||
db (d/db auto-ap.datomic/conn)
|
||||
invoice-totals (->> data
|
||||
(drop 1)
|
||||
(group-by first)
|
||||
(map (fn [[k values]]
|
||||
[(Long/parseLong k)
|
||||
(reduce + 0.0
|
||||
(->> values
|
||||
(map (fn [[_ _ amount]]
|
||||
(- (Double/parseDouble amount))))))
|
||||
]))
|
||||
(into {}))]
|
||||
(->>
|
||||
(for [[invoice-id expense-account-id amount expense-account location] (drop 1 data)
|
||||
:let [
|
||||
invoice-id (Long/parseLong invoice-id)
|
||||
|
||||
invoice (d/entity db invoice-id)
|
||||
current-total (:invoice/total invoice)
|
||||
target-total (invoice-totals invoice-id)
|
||||
|
||||
expense-account-id (Long/parseLong expense-account-id)
|
||||
current-expense-account-code (:account/numeric-code (:invoice-expense-account/account (d/entity db expense-account-id)))
|
||||
target-expense-account-code (Long/parseLong (str/trim expense-account))
|
||||
[[target-expense-account-id]] (vec (d/q
|
||||
'[:find ?a
|
||||
:in $ ?c
|
||||
:where [?a :account/numeric-code ?c]
|
||||
]
|
||||
db target-expense-account-code))
|
||||
|
||||
current-expense-account-amount (:invoice-expense-account/amount (d/entity db expense-account-id))
|
||||
target-expense-account-amount (- (Double/parseDouble amount))
|
||||
|
||||
|
||||
current-expense-account-location (:invoice-expense-account/location (d/entity db expense-account-id))
|
||||
target-expense-account-location location
|
||||
|
||||
|
||||
[[payment-id payment-amount]] (vec (d/q
|
||||
'[:find ?p ?a
|
||||
:in $ ?i
|
||||
:where [?ip :invoice-payment/invoice ?i]
|
||||
[?ip :invoice-payment/amount ?a]
|
||||
[?ip :invoice-payment/payment ?p]
|
||||
]
|
||||
db invoice-id))]]
|
||||
|
||||
[
|
||||
(when (not (auto-ap.utils/dollars= current-total target-total))
|
||||
(if payment-id
|
||||
(println "Cannot update" invoice-id " of " current-total "to be" target-total "because it has a payment (" payment-id ") of" payment-amount )
|
||||
{:db/id invoice-id
|
||||
:invoice/total target-total}))
|
||||
|
||||
(when (and (not (auto-ap.utils/dollars= current-expense-account-amount target-expense-account-amount))
|
||||
(or (auto-ap.utils/dollars= current-total target-total)
|
||||
(not payment-id)))
|
||||
{:db/id expense-account-id
|
||||
:invoice-expense-account/amount target-expense-account-amount})
|
||||
|
||||
(when (not= current-expense-account-location
|
||||
target-expense-account-location)
|
||||
{:db/id expense-account-id
|
||||
:invoice-expense-account/location target-expense-account-location})
|
||||
|
||||
(when (not= target-expense-account-code current-expense-account-code )
|
||||
{:db/id expense-account-id
|
||||
:invoice-expense-account/account target-expense-account-id})]
|
||||
|
||||
#_(println (auto-ap.utils/dollars= current-total amount) current-total amount current-expense-account-code expense-account-code)
|
||||
)
|
||||
(mapcat identity)
|
||||
(filter identity)
|
||||
vec)))
|
||||
|
||||
|
||||
(defn get-schema [prefix]
|
||||
(->> (d/q '[:find ?i
|
||||
:in $ ?p
|
||||
:where [_ :db/ident ?i]
|
||||
[(namespace ?i) ?p]] (d/db auto-ap.datomic/conn) prefix)
|
||||
(mapcat identity)
|
||||
vec
|
||||
))
|
||||
|
||||
(defn manually-add-transaction []
|
||||
(auto-ap.yodlee.import/transactions->txs [{:postDate "2014-01-04"
|
||||
:accountId 1234
|
||||
:date "2021-06-05"
|
||||
:id 1
|
||||
:amount {:amount -1743.25}
|
||||
:description {:original "original-description"
|
||||
:simple "simple-description"}
|
||||
:merchant {:id "123"
|
||||
:name "456"}
|
||||
:baseType "DEBIT"
|
||||
:status "POSTED"
|
||||
|
||||
:bank-account {:db/id [:bank-account/code "NGAK-1"]
|
||||
:client/_bank-accounts {:db/id 17592186045456
|
||||
:client/locations ["MH"]}}}]
|
||||
:bank-account
|
||||
(fn noop-rule [transaction locations]
|
||||
transaction)
|
||||
#{}))
|
||||
|
||||
|
||||
Reference in New Issue
Block a user