Migrates back to datomic on-prem
This commit is contained in:
5
.clj-kondo/rewrite-clj/rewrite-clj/config.edn
Normal file
5
.clj-kondo/rewrite-clj/rewrite-clj/config.edn
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
{:lint-as
|
||||||
|
{rewrite-clj.zip/subedit-> clojure.core/->
|
||||||
|
rewrite-clj.zip/subedit->> clojure.core/->>
|
||||||
|
rewrite-clj.zip/edit-> clojure.core/->
|
||||||
|
rewrite-clj.zip/edit->> clojure.core/->>}}
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
(:require [clj-time.core :as time]
|
(:require [clj-time.core :as time]
|
||||||
[clj-time.coerce :as coerce]
|
[clj-time.coerce :as coerce]
|
||||||
[clj-time.format :as f]
|
[clj-time.format :as f]
|
||||||
[datomic.client.api :as dc]))
|
[datomic.api :as dc]))
|
||||||
|
|
||||||
#_{:clj-kondo/ignore [:clojure-lsp/unused-public-var]}
|
#_{:clj-kondo/ignore [:clojure-lsp/unused-public-var]}
|
||||||
(defn dollars-0? [amt]
|
(defn dollars-0? [amt]
|
||||||
|
|||||||
@@ -1,406 +1,12 @@
|
|||||||
(ns iol-ion.tx
|
(ns iol-ion.tx
|
||||||
(:require [datomic.client.api :as dc])
|
(:require [datomic.api :as dc]
|
||||||
|
[iol-ion.utils])
|
||||||
(:import [java.util UUID]))
|
(:import [java.util UUID]))
|
||||||
|
|
||||||
(defn random-tempid []
|
(def random-tempid iol-ion.utils/random-tempid)
|
||||||
(str (UUID/randomUUID)))
|
(def by iol-ion.utils/by)
|
||||||
|
(def pull-many iol-ion.utils/pull-many)
|
||||||
(defn by
|
(def remove-nils iol-ion.utils/remove-nils)
|
||||||
([f xs]
|
|
||||||
(by f identity xs))
|
|
||||||
([f fv xs]
|
|
||||||
(reduce
|
|
||||||
#(assoc %1 (f %2) (fv %2))
|
|
||||||
{}
|
|
||||||
xs)))
|
|
||||||
|
|
||||||
(defn pull-many [db read ids ]
|
|
||||||
(->> (dc/q '[:find (pull ?e r)
|
|
||||||
:in $ [?e ...] r]
|
|
||||||
db
|
|
||||||
ids
|
|
||||||
read)
|
|
||||||
(map first)))
|
|
||||||
|
|
||||||
(declare upsert-entity)
|
|
||||||
|
|
||||||
(defn reset-rels [db e a vs]
|
|
||||||
(assert (every? :db/id vs) (format "In order to reset attribute %s, every value must have :db/id" a))
|
|
||||||
(let [ids (when-not (string? e)
|
|
||||||
(->> (dc/q '[:find ?z
|
|
||||||
:in $ ?e ?a
|
|
||||||
:where [?e ?a ?z]]
|
|
||||||
db e a)
|
|
||||||
(map first)))
|
|
||||||
new-id-set (set (map :db/id vs))
|
|
||||||
retract-ids (filter (complement new-id-set) ids)
|
|
||||||
{is-component? :db/isComponent} (dc/pull db [:db/isComponent] a)
|
|
||||||
new-rels (filter (complement (set ids)) (map :db/id vs))]
|
|
||||||
(-> []
|
|
||||||
(into (map (fn [i] (if is-component?
|
|
||||||
[:db/retractEntity i]
|
|
||||||
[:db/retract e a i ])) retract-ids))
|
|
||||||
(into (map (fn [i] [:db/add e a i]) new-rels))
|
|
||||||
(into (mapcat (fn [i] (upsert-entity db i)) vs)))))
|
|
||||||
|
|
||||||
(defn reset-scalars [db e a vs]
|
|
||||||
|
|
||||||
(let [extant (when-not (string? e)
|
|
||||||
(->> (dc/q '[:find ?z
|
|
||||||
:in $ ?e ?a
|
|
||||||
:where [?e ?a ?z]]
|
|
||||||
db e a)
|
|
||||||
(map first)))
|
|
||||||
retracts (filter (complement (set vs)) extant)
|
|
||||||
new (filter (complement (set extant)) vs)]
|
|
||||||
(-> []
|
|
||||||
(into (map (fn [i] [:db/retract e a i ]) retracts))
|
|
||||||
(into (map (fn [i] [:db/add e a i]) new)))))
|
|
||||||
|
|
||||||
|
|
||||||
;; TODO unit test this
|
|
||||||
(defn upsert-entity [db entity]
|
|
||||||
(assert (or (:db/id entity)
|
|
||||||
(:db/ident entity))
|
|
||||||
(str "Cannot upsert without :db/id or :db/ident, " entity))
|
|
||||||
(let [e (or (:db/id entity) (:db/ident entity))
|
|
||||||
is-new? (string? e)
|
|
||||||
extant-entity (when-not is-new?
|
|
||||||
(dc/pull db (keys entity) (or (:db/id entity) (:db/ident entity))))
|
|
||||||
ident->value-type (by :db/ident (comp :db/ident
|
|
||||||
:db/valueType)
|
|
||||||
(pull-many
|
|
||||||
db
|
|
||||||
[:db/valueType :db/ident]
|
|
||||||
(keys entity)))
|
|
||||||
|
|
||||||
ident->cardinality (by :db/ident (comp :db/ident
|
|
||||||
:db/cardinality)
|
|
||||||
(pull-many
|
|
||||||
db
|
|
||||||
[:db/cardinality :db/ident]
|
|
||||||
(keys entity)))
|
|
||||||
ops (->> entity
|
|
||||||
(reduce
|
|
||||||
(fn [ops [a v]]
|
|
||||||
(cond
|
|
||||||
(= :db/id a)
|
|
||||||
ops
|
|
||||||
|
|
||||||
(= :db/ident a)
|
|
||||||
ops
|
|
||||||
|
|
||||||
(or (= v (a extant-entity))
|
|
||||||
(= v (:db/ident (a extant-entity) :nope))
|
|
||||||
(= v (:db/id (a extant-entity)) :nope))
|
|
||||||
ops
|
|
||||||
|
|
||||||
(and (nil? v)
|
|
||||||
(not (nil? (a extant-entity))))
|
|
||||||
(if (= :db.cardinality/many (ident->cardinality a))
|
|
||||||
(into ops (map (fn [v]
|
|
||||||
[:db/retract e a (cond-> v
|
|
||||||
(:db/id v) :db/id)])
|
|
||||||
(a extant-entity)))
|
|
||||||
|
|
||||||
(conj ops [:db/retract e a (cond-> (a extant-entity)
|
|
||||||
(:db/id (a extant-entity)) :db/id)]))
|
|
||||||
|
|
||||||
(nil? v)
|
|
||||||
ops
|
|
||||||
|
|
||||||
;; reset relationships if it's refs, and not a lookup (i.e., seq of maps, or empty seq)
|
|
||||||
|
|
||||||
(and (sequential? v) (= :db.type/tuple (ident->value-type a)))
|
|
||||||
(conj ops [:db/add e a v])
|
|
||||||
|
|
||||||
(and (sequential? v) (= :db.type/ref (ident->value-type a)) (every? map? v))
|
|
||||||
(into ops (reset-rels db e a v))
|
|
||||||
|
|
||||||
|
|
||||||
(= :db.cardinality/many (ident->cardinality a))
|
|
||||||
(into ops (reset-scalars db e a v))
|
|
||||||
|
|
||||||
(and (sequential? v) (not= :db.type/ref (ident->value-type a)))
|
|
||||||
(into ops (reset-scalars db e a v))
|
|
||||||
|
|
||||||
(and (map? v)
|
|
||||||
(= :db.type/ref (ident->value-type a)))
|
|
||||||
(let [id (or (:db/id v) (random-tempid))]
|
|
||||||
(-> ops
|
|
||||||
(conj [:db/add e a id])
|
|
||||||
(into (upsert-entity db (assoc v :db/id id)))))
|
|
||||||
|
|
||||||
:else
|
|
||||||
(conj ops [:db/add e a v])
|
|
||||||
))
|
|
||||||
[]))]
|
|
||||||
ops))
|
|
||||||
|
|
||||||
(defn min-by [sorter]
|
|
||||||
(->> sorter
|
|
||||||
sort
|
|
||||||
last
|
|
||||||
last))
|
|
||||||
|
|
||||||
(defn get-line-items-after [db journal-entry]
|
|
||||||
(for [jel (:journal-entry/line-items journal-entry)
|
|
||||||
:let [next-jel (->> (dc/index-pull db {:index :avet
|
|
||||||
:selector [:db/id :journal-entry-line/client+account+location+date]
|
|
||||||
:start [:journal-entry-line/client+account+location+date
|
|
||||||
(:journal-entry-line/client+account+location+date jel)
|
|
||||||
(:db/id jel)]
|
|
||||||
:limit 3
|
|
||||||
})
|
|
||||||
(filter (fn line-must-match-client-account-location [result]
|
|
||||||
(and
|
|
||||||
(= (take 3 (:journal-entry-line/client+account+location+date result))
|
|
||||||
(take 3 (:journal-entry-line/client+account+location+date jel)))
|
|
||||||
(not= (:db/id jel)
|
|
||||||
(:db/id result)))
|
|
||||||
))
|
|
||||||
first
|
|
||||||
:db/id)]
|
|
||||||
:when next-jel]
|
|
||||||
next-jel))
|
|
||||||
|
|
||||||
(def extant-read '[:db/id :journal-entry/date :journal-entry/client {:journal-entry/line-items [:journal-entry-line/account :journal-entry-line/location :db/id :journal-entry-line/client+account+location+date]}])
|
|
||||||
|
|
||||||
|
|
||||||
(defn calc-client+account+location+date [je jel]
|
|
||||||
[(or
|
|
||||||
(:db/id (:journal-entry/client je))
|
|
||||||
(:journal-entry/client je))
|
|
||||||
(or (:db/id (:journal-entry-line/account jel))
|
|
||||||
(:journal-entry-line/account jel))
|
|
||||||
(-> jel :journal-entry-line/location)
|
|
||||||
(-> je :journal-entry/date)])
|
|
||||||
|
|
||||||
(defn upsert-ledger [db ledger-entry]
|
|
||||||
(assert (:journal-entry/date ledger-entry) "Must at least provide date when updating ledger")
|
|
||||||
(assert (:journal-entry/client ledger-entry) "Must at least provide client when updating ledger")
|
|
||||||
;; TODO these are not always true
|
|
||||||
;; (assert (every? :journal-entry-line/account (:journal-entry/line-items ledger-entry)) "must at least provide account when updating ledger")
|
|
||||||
;; (assert (every? :journal-entry-line/location (:journal-entry/line-items ledger-entry)) "Must at least provide location when updating ledger")
|
|
||||||
(let [extant-entry (or (when-let [original-entity (:journal-entry/original-entity ledger-entry)]
|
|
||||||
(dc/pull db extant-read [:journal-entry/original-entity original-entity]))
|
|
||||||
(when-let [external-id (:journal-entry/external-id ledger-entry)]
|
|
||||||
(dc/pull db extant-read [:journal-entry/external-id external-id])))
|
|
||||||
extant-entry-exists? (:db/id extant-entry)]
|
|
||||||
|
|
||||||
(cond->
|
|
||||||
(upsert-entity db (into (-> ledger-entry
|
|
||||||
(assoc :db/id (or
|
|
||||||
(:db/id ledger-entry)
|
|
||||||
(:db/id extant-entry)
|
|
||||||
(random-tempid)))
|
|
||||||
(update :journal-entry/line-items
|
|
||||||
(fn [lis]
|
|
||||||
(mapv #(-> %
|
|
||||||
(assoc :journal-entry-line/dirty true)
|
|
||||||
(assoc :journal-entry-line/client+account+location+date
|
|
||||||
(calc-client+account+location+date ledger-entry %)))
|
|
||||||
lis))))
|
|
||||||
))
|
|
||||||
extant-entry-exists? (into (map (fn [li]
|
|
||||||
{:journal-entry-line/dirty true
|
|
||||||
:db/id li})
|
|
||||||
(get-line-items-after db extant-entry))))))
|
|
||||||
|
|
||||||
(defn remove-nils [m]
|
|
||||||
(let [result (reduce-kv
|
|
||||||
(fn [m k v]
|
|
||||||
(if (not (nil? v))
|
|
||||||
(assoc m k v)
|
|
||||||
m
|
|
||||||
))
|
|
||||||
{}
|
|
||||||
m)]
|
|
||||||
(if (seq result)
|
|
||||||
result
|
|
||||||
nil)))
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
(defn invoice->journal-entry
|
|
||||||
([db invoice-id]
|
|
||||||
(invoice->journal-entry db invoice-id invoice-id))
|
|
||||||
;; the 3-arity version allows you to pass a potential tempid in instead of the invoice-id,
|
|
||||||
;; which would be a temporary value after the transaction
|
|
||||||
([db invoice-id raw-invoice-id]
|
|
||||||
(let [entity (dc/pull db
|
|
||||||
'[:invoice/total
|
|
||||||
:invoice/exclude-from-ledger
|
|
||||||
:invoice/outstanding-balance
|
|
||||||
:invoice/date
|
|
||||||
{:invoice/vendor [:db/id :vendor/name]
|
|
||||||
:invoice/client [:db/id :client/code]
|
|
||||||
:invoice/payment [:db/id {:payment/status [:db/ident]}]
|
|
||||||
:invoice/status [:db/ident]
|
|
||||||
:invoice/import-status [:db/ident]
|
|
||||||
:invoice/expense-accounts [:invoice-expense-account/account
|
|
||||||
:invoice-expense-account/amount
|
|
||||||
:invoice-expense-account/location]}]
|
|
||||||
invoice-id)
|
|
||||||
credit-invoice? (< (:invoice/total entity 0.0) 0.0)]
|
|
||||||
(when-not (or
|
|
||||||
(not (:invoice/total entity))
|
|
||||||
(= true (:invoice/exclude-from-ledger entity))
|
|
||||||
(= :import-status/pending (:db/ident (:invoice/import-status entity)))
|
|
||||||
(= :invoice-status/voided (:db/ident (:invoice/status entity)))
|
|
||||||
(< -0.001 (:invoice/total entity) 0.001))
|
|
||||||
|
|
||||||
(remove-nils
|
|
||||||
{:journal-entry/source "invoice"
|
|
||||||
:journal-entry/client (:db/id (:invoice/client entity))
|
|
||||||
:journal-entry/date (:invoice/date entity)
|
|
||||||
:journal-entry/original-entity raw-invoice-id
|
|
||||||
:journal-entry/vendor (:db/id (:invoice/vendor entity))
|
|
||||||
:journal-entry/amount (Math/abs (:invoice/total entity))
|
|
||||||
|
|
||||||
:journal-entry/line-items (into [(cond-> {:db/id (str raw-invoice-id "-" 0)
|
|
||||||
:journal-entry-line/account :account/accounts-payable
|
|
||||||
:journal-entry-line/location "A"
|
|
||||||
}
|
|
||||||
credit-invoice? (assoc :journal-entry-line/debit (Math/abs (:invoice/total entity)))
|
|
||||||
(not credit-invoice?) (assoc :journal-entry-line/credit (Math/abs (:invoice/total entity))))]
|
|
||||||
(map-indexed (fn [i ea]
|
|
||||||
(cond->
|
|
||||||
{:db/id (str raw-invoice-id "-" (inc i))
|
|
||||||
:journal-entry-line/account (:db/id (:invoice-expense-account/account ea))
|
|
||||||
:journal-entry-line/location (or (:invoice-expense-account/location ea) "HQ")
|
|
||||||
}
|
|
||||||
credit-invoice? (assoc :journal-entry-line/credit (Math/abs (:invoice-expense-account/amount ea)))
|
|
||||||
(not credit-invoice?) (assoc :journal-entry-line/debit (Math/abs (:invoice-expense-account/amount ea)))))
|
|
||||||
(:invoice/expense-accounts entity)))
|
|
||||||
:journal-entry/cleared (and (< (:invoice/outstanding-balance entity) 0.01)
|
|
||||||
(every? #(= :payment-status/cleared (:payment/status %)) (:invoice/payments entity))
|
|
||||||
)})))))
|
|
||||||
|
|
||||||
(defn upsert-invoice [db invoice]
|
|
||||||
(let [
|
|
||||||
upserted-entity (upsert-entity db invoice)
|
|
||||||
with-invoice (try (dc/with db {:tx-data upserted-entity})
|
|
||||||
(catch ClassCastException e
|
|
||||||
(println "Dev local does not support with in tx functions. :(")
|
|
||||||
(dc/with (dc/with-db @(resolve 'auto-ap.datomic/conn)) {:tx-data upserted-entity})
|
|
||||||
))
|
|
||||||
invoice-id (or (-> with-invoice :tempids (get (:db/id invoice)))
|
|
||||||
(:db/id invoice))
|
|
||||||
journal-entry (invoice->journal-entry (:db-after with-invoice)
|
|
||||||
invoice-id
|
|
||||||
(:db/id invoice))]
|
|
||||||
|
|
||||||
(into upserted-entity
|
|
||||||
(if journal-entry
|
|
||||||
(upsert-ledger db journal-entry)
|
|
||||||
[[:db/retractEntity [:journal-entry/original-entity (:db/id invoice)]]]))))
|
|
||||||
|
|
||||||
(defn propose-invoice [db invoice]
|
|
||||||
(let [existing? (boolean (seq (dc/q '[:find ?i
|
|
||||||
:in $ ?invoice-number ?client ?vendor
|
|
||||||
:where
|
|
||||||
[?i :invoice/invoice-number ?invoice-number]
|
|
||||||
[?i :invoice/client ?client]
|
|
||||||
[?i :invoice/vendor ?vendor]
|
|
||||||
(not [?i :invoice/status :invoice-status/voided])]
|
|
||||||
db
|
|
||||||
(:invoice/invoice-number invoice)
|
|
||||||
(:invoice/client invoice)
|
|
||||||
(:invoice/vendor invoice))))]
|
|
||||||
(if existing?
|
|
||||||
[]
|
|
||||||
(upsert-invoice db invoice))))
|
|
||||||
|
|
||||||
|
|
||||||
(defn transaction->journal-entry
|
|
||||||
([db transaction-id]
|
|
||||||
(transaction->journal-entry db transaction-id transaction-id))
|
|
||||||
;; the 3-arity version allows you to pass a potential tempid in instead of the invoice-id,
|
|
||||||
;; which would be a temporary value after the transaction
|
|
||||||
([db transaction-id raw-transaction-id]
|
|
||||||
(let [entity (dc/pull db [:transaction/client
|
|
||||||
:transaction/date
|
|
||||||
:transaction/description-original
|
|
||||||
:db/id
|
|
||||||
:transaction/vendor
|
|
||||||
:transaction/amount
|
|
||||||
:transaction/cleared-against
|
|
||||||
{:transaction/accounts [:transaction-account/account
|
|
||||||
:transaction-account/location
|
|
||||||
:transaction-account/amount]
|
|
||||||
:transaction/approval-status [:db/ident]
|
|
||||||
:transaction/bank-account [:db/id {:bank-account/type [:db/ident]}]}]
|
|
||||||
transaction-id)
|
|
||||||
decreasing? (< (or (:transaction/amount entity) 0.0) 0.0)
|
|
||||||
credit-from-bank? decreasing?
|
|
||||||
debit-from-bank? (not decreasing?)]
|
|
||||||
(when (and (not (= :transaction-approval-status/excluded (:db/ident (:transaction/approval-status entity))))
|
|
||||||
(not (= :transaction-approval-status/suppressed (:db/ident (:transaction/approval-status entity))))
|
|
||||||
(:transaction/amount entity)
|
|
||||||
(not (< -0.001 (:transaction/amount entity) 0.001)))
|
|
||||||
(remove-nils
|
|
||||||
{:journal-entry/source "transaction"
|
|
||||||
:journal-entry/client (:db/id (:transaction/client entity))
|
|
||||||
:journal-entry/date (:transaction/date entity)
|
|
||||||
:journal-entry/original-entity raw-transaction-id
|
|
||||||
:journal-entry/alternate-description (:transaction/description-original entity)
|
|
||||||
:journal-entry/vendor (:db/id (:transaction/vendor entity))
|
|
||||||
:journal-entry/amount (Math/abs (:transaction/amount entity))
|
|
||||||
:journal-entry/cleared-against (:transaction/cleared-against entity)
|
|
||||||
|
|
||||||
:journal-entry/line-items (into [(remove-nils {:journal-entry-line/account (:db/id (:transaction/bank-account entity))
|
|
||||||
:db/id (str raw-transaction-id "-" 0)
|
|
||||||
:journal-entry-line/location "A"
|
|
||||||
:journal-entry-line/credit (when credit-from-bank?
|
|
||||||
(Math/abs (:transaction/amount entity)))
|
|
||||||
:journal-entry-line/debit (when debit-from-bank?
|
|
||||||
(Math/abs (:transaction/amount entity)))})
|
|
||||||
]
|
|
||||||
(map-indexed
|
|
||||||
(fn [i a]
|
|
||||||
(remove-nils{
|
|
||||||
:db/id (str raw-transaction-id "-" (inc i))
|
|
||||||
:journal-entry-line/account (:db/id (:transaction-account/account a))
|
|
||||||
:journal-entry-line/location (:transaction-account/location a)
|
|
||||||
:journal-entry-line/debit (when credit-from-bank?
|
|
||||||
(Math/abs (:transaction-account/amount a)))
|
|
||||||
:journal-entry-line/credit (when debit-from-bank?
|
|
||||||
(Math/abs (:transaction-account/amount a)))}))
|
|
||||||
(if (seq (:transaction/accounts entity))
|
|
||||||
(:transaction/accounts entity)
|
|
||||||
[{:transaction-account/amount (:transaction/amount entity)}])))
|
|
||||||
|
|
||||||
:journal-entry/cleared true})))))
|
|
||||||
|
|
||||||
(defn upsert-transaction [db transaction]
|
|
||||||
;; because some transactions will reference temp ids, you have to dissoc them, like :transaction/payment
|
|
||||||
(let [upserted-entity (upsert-entity db (dissoc transaction :transaction/payment :import-batch/_entry))
|
|
||||||
with-transaction (try (dc/with db {:tx-data upserted-entity})
|
|
||||||
(catch ClassCastException e
|
|
||||||
(println "Dev local does not support with in tx functions. :(")
|
|
||||||
(dc/with (dc/with-db @(resolve 'auto-ap.datomic/conn)) {:tx-data upserted-entity})
|
|
||||||
))
|
|
||||||
transaction-id (or (-> with-transaction :tempids (get (:db/id transaction)))
|
|
||||||
(:db/id transaction))
|
|
||||||
journal-entry (transaction->journal-entry (:db-after with-transaction)
|
|
||||||
transaction-id
|
|
||||||
(:db/id transaction))]
|
|
||||||
(into (upsert-entity db transaction)
|
|
||||||
(if journal-entry
|
|
||||||
(upsert-ledger db journal-entry)
|
|
||||||
[[:db/retractEntity [:journal-entry/original-entity (:db/id transaction)]]]))))
|
|
||||||
|
|
||||||
|
|
||||||
(defn pay [db e amount]
|
|
||||||
(let [current-outstanding-balance (-> (dc/pull db [:invoice/outstanding-balance] e) :invoice/outstanding-balance)
|
|
||||||
new-outstanding-balance (- current-outstanding-balance amount)]
|
|
||||||
(upsert-invoice db {:db/id e
|
|
||||||
:invoice/outstanding-balance new-outstanding-balance
|
|
||||||
:invoice/status (if (> new-outstanding-balance 0)
|
|
||||||
:invoice-status/unpaid
|
|
||||||
:invoice-status/paid)})))
|
|
||||||
|
|
||||||
|
|
||||||
;; TODO expected-deposit ledger entry
|
;; TODO expected-deposit ledger entry
|
||||||
@@ -424,5 +30,7 @@
|
|||||||
:location "A"
|
:location "A"
|
||||||
:account :account/ccp}]}))
|
:account :account/ccp}]}))
|
||||||
|
|
||||||
(defn plus [db e a amount]
|
|
||||||
[[:db/add e a (-> (dc/pull db [a] e) a (+ amount))]])
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
11
iol_ion/src/iol_ion/tx/pay.clj
Normal file
11
iol_ion/src/iol_ion/tx/pay.clj
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
(ns iol-ion.tx.pay
|
||||||
|
(:require [datomic.api :as dc]))
|
||||||
|
|
||||||
|
(defn pay [db e amount]
|
||||||
|
(let [current-outstanding-balance (-> (dc/pull db [:invoice/outstanding-balance] e) :invoice/outstanding-balance)
|
||||||
|
new-outstanding-balance (- current-outstanding-balance amount)]
|
||||||
|
[[:upsert-invoice {:db/id e
|
||||||
|
:invoice/outstanding-balance new-outstanding-balance
|
||||||
|
:invoice/status (if (> new-outstanding-balance 0)
|
||||||
|
:invoice-status/unpaid
|
||||||
|
:invoice-status/paid)}]]))
|
||||||
5
iol_ion/src/iol_ion/tx/plus.clj
Normal file
5
iol_ion/src/iol_ion/tx/plus.clj
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
(ns iol-ion.tx.plus
|
||||||
|
(:require [datomic.api :as dc]))
|
||||||
|
|
||||||
|
(defn plus [db e a amount]
|
||||||
|
[[:db/add e a (-> (dc/pull db [a] e) a (+ amount))]])
|
||||||
18
iol_ion/src/iol_ion/tx/propose_invoice.clj
Normal file
18
iol_ion/src/iol_ion/tx/propose_invoice.clj
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
(ns iol-ion.tx.propose-invoice
|
||||||
|
(:require [datomic.api :as dc]))
|
||||||
|
|
||||||
|
(defn propose-invoice [db invoice]
|
||||||
|
(let [existing? (boolean (seq (dc/q '[:find ?i
|
||||||
|
:in $ ?invoice-number ?client ?vendor
|
||||||
|
:where
|
||||||
|
[?i :invoice/invoice-number ?invoice-number]
|
||||||
|
[?i :invoice/client ?client]
|
||||||
|
[?i :invoice/vendor ?vendor]
|
||||||
|
(not [?i :invoice/status :invoice-status/voided])]
|
||||||
|
db
|
||||||
|
(:invoice/invoice-number invoice)
|
||||||
|
(:invoice/client invoice)
|
||||||
|
(:invoice/vendor invoice))))]
|
||||||
|
(if existing?
|
||||||
|
[]
|
||||||
|
[[:upsert-invoice invoice]])))
|
||||||
21
iol_ion/src/iol_ion/tx/reset_rels.clj
Normal file
21
iol_ion/src/iol_ion/tx/reset_rels.clj
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
(ns iol-ion.tx.reset-rels
|
||||||
|
(:require [datomic.api :as dc]))
|
||||||
|
|
||||||
|
(defn reset-rels [db e a vs]
|
||||||
|
(assert (every? :db/id vs) (format "In order to reset attribute %s, every value must have :db/id" a))
|
||||||
|
(let [ids (when-not (string? e)
|
||||||
|
(->> (dc/q '[:find ?z
|
||||||
|
:in $ ?e ?a
|
||||||
|
:where [?e ?a ?z]]
|
||||||
|
db e a)
|
||||||
|
(map first)))
|
||||||
|
new-id-set (set (map :db/id vs))
|
||||||
|
retract-ids (filter (complement new-id-set) ids)
|
||||||
|
{is-component? :db/isComponent} (dc/pull db [:db/isComponent] a)
|
||||||
|
new-rels (filter (complement (set ids)) (map :db/id vs))]
|
||||||
|
(-> []
|
||||||
|
(into (map (fn [i] (if is-component?
|
||||||
|
[:db/retractEntity i]
|
||||||
|
[:db/retract e a i ])) retract-ids))
|
||||||
|
(into (map (fn [i] [:db/add e a i]) new-rels))
|
||||||
|
(into (map (fn [i] [:upsert-entity i]) vs)))))
|
||||||
16
iol_ion/src/iol_ion/tx/reset_scalars.clj
Normal file
16
iol_ion/src/iol_ion/tx/reset_scalars.clj
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
(ns iol-ion.tx.reset-scalars
|
||||||
|
(:require [datomic.api :as dc]))
|
||||||
|
|
||||||
|
(defn reset-scalars [db e a vs]
|
||||||
|
|
||||||
|
(let [extant (when-not (string? e)
|
||||||
|
(->> (dc/q '[:find ?z
|
||||||
|
:in $ ?e ?a
|
||||||
|
:where [?e ?a ?z]]
|
||||||
|
db e a)
|
||||||
|
(map first)))
|
||||||
|
retracts (filter (complement (set vs)) extant)
|
||||||
|
new (filter (complement (set extant)) vs)]
|
||||||
|
(-> []
|
||||||
|
(into (map (fn [i] [:db/retract e a i ]) retracts))
|
||||||
|
(into (map (fn [i] [:db/add e a i]) new)))))
|
||||||
103
iol_ion/src/iol_ion/tx/upsert_entity.clj
Normal file
103
iol_ion/src/iol_ion/tx/upsert_entity.clj
Normal file
@@ -0,0 +1,103 @@
|
|||||||
|
(ns iol-ion.tx.upsert-entity
|
||||||
|
(:require [datomic.api :as dc])
|
||||||
|
(:import [java.util UUID]))
|
||||||
|
|
||||||
|
|
||||||
|
(defn -random-tempid []
|
||||||
|
(str (UUID/randomUUID)))
|
||||||
|
|
||||||
|
(defn -by
|
||||||
|
[f fv xs]
|
||||||
|
(reduce
|
||||||
|
#(assoc %1 (f %2) (fv %2))
|
||||||
|
{}
|
||||||
|
xs))
|
||||||
|
|
||||||
|
(defn -pull-many [db read ids ]
|
||||||
|
(->> (dc/q '[:find (pull ?e r)
|
||||||
|
:in $ [?e ...] r]
|
||||||
|
db
|
||||||
|
ids
|
||||||
|
read)
|
||||||
|
(map first)))
|
||||||
|
|
||||||
|
|
||||||
|
(defn upsert-entity [db entity]
|
||||||
|
(when-not (or (:db/id entity)
|
||||||
|
(:db/ident entity))
|
||||||
|
(datomic.api/cancel {:cognitect.anomalies/category :cognitect.anomalies/incorrect
|
||||||
|
:cognitect.anomalies/message
|
||||||
|
(str "Cannot upsert without :db/id or :db/ident, " entity)}))
|
||||||
|
[]
|
||||||
|
(let [e (or (:db/id entity) (:db/ident entity))
|
||||||
|
is-new? (string? e)
|
||||||
|
extant-entity (when-not is-new?
|
||||||
|
(dc/pull db (keys entity) (or (:db/id entity) (:db/ident entity))))
|
||||||
|
ident->value-type (-by :db/ident (comp :db/ident
|
||||||
|
:db/valueType)
|
||||||
|
(-pull-many
|
||||||
|
db
|
||||||
|
[{:db/valueType [:db/ident]} :db/ident]
|
||||||
|
(keys entity)))
|
||||||
|
|
||||||
|
ident->cardinality (-by :db/ident (comp :db/ident
|
||||||
|
:db/cardinality)
|
||||||
|
(-pull-many
|
||||||
|
db
|
||||||
|
[{:db/cardinality [:db/ident]} :db/ident]
|
||||||
|
(keys entity)))
|
||||||
|
ops (->> entity
|
||||||
|
(reduce
|
||||||
|
(fn [ops [a v]]
|
||||||
|
(cond
|
||||||
|
(= :db/id a)
|
||||||
|
ops
|
||||||
|
|
||||||
|
(= :db/ident a)
|
||||||
|
ops
|
||||||
|
|
||||||
|
(or (= v (a extant-entity))
|
||||||
|
(= v (:db/ident (a extant-entity) :nope))
|
||||||
|
(= v (:db/id (a extant-entity)) :nope))
|
||||||
|
ops
|
||||||
|
|
||||||
|
(and (nil? v)
|
||||||
|
(not (nil? (a extant-entity))))
|
||||||
|
(if (= :db.cardinality/many (ident->cardinality a))
|
||||||
|
(into ops (map (fn [v]
|
||||||
|
[:db/retract e a (cond-> v
|
||||||
|
(:db/id v) :db/id)])
|
||||||
|
(a extant-entity)))
|
||||||
|
|
||||||
|
(conj ops [:db/retract e a (cond-> (a extant-entity)
|
||||||
|
(:db/id (a extant-entity)) :db/id)]))
|
||||||
|
|
||||||
|
(nil? v)
|
||||||
|
ops
|
||||||
|
|
||||||
|
;; reset relationships if it's refs, and not a lookup (i.e., seq of maps, or empty seq)
|
||||||
|
|
||||||
|
(and (sequential? v) (= :db.type/tuple (ident->value-type a)))
|
||||||
|
(conj ops [:db/add e a v])
|
||||||
|
|
||||||
|
(and (sequential? v) (= :db.type/ref (ident->value-type a)) (every? map? v))
|
||||||
|
(into ops [[:reset-rels e a v]])
|
||||||
|
|
||||||
|
(= :db.cardinality/many (ident->cardinality a))
|
||||||
|
(into ops [[:reset-scalars e a v]])
|
||||||
|
|
||||||
|
(and (sequential? v) (not= :db.type/ref (ident->value-type a)))
|
||||||
|
(into ops [[:reset-scalars e a v]])
|
||||||
|
|
||||||
|
(and (map? v)
|
||||||
|
(= :db.type/ref (ident->value-type a)))
|
||||||
|
(let [id (or (:db/id v) (-random-tempid))]
|
||||||
|
(-> ops
|
||||||
|
(conj [:db/add e a id])
|
||||||
|
(into [[:upsert-entity (assoc v :db/id id)]])))
|
||||||
|
|
||||||
|
:else
|
||||||
|
(conj ops [:db/add e a v])
|
||||||
|
))
|
||||||
|
[]))]
|
||||||
|
ops))
|
||||||
81
iol_ion/src/iol_ion/tx/upsert_invoice.clj
Normal file
81
iol_ion/src/iol_ion/tx/upsert_invoice.clj
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
(ns iol-ion.tx.upsert-invoice
|
||||||
|
(:require [datomic.api :as dc]))
|
||||||
|
|
||||||
|
(defn -remove-nils [m]
|
||||||
|
(let [result (reduce-kv
|
||||||
|
(fn [m k v]
|
||||||
|
(if (not (nil? v))
|
||||||
|
(assoc m k v)
|
||||||
|
m
|
||||||
|
))
|
||||||
|
{}
|
||||||
|
m)]
|
||||||
|
(if (seq result)
|
||||||
|
result
|
||||||
|
nil)))
|
||||||
|
|
||||||
|
(defn invoice->journal-entry
|
||||||
|
[db invoice-id raw-invoice-id]
|
||||||
|
(let [entity (dc/pull db
|
||||||
|
'[:invoice/total
|
||||||
|
:invoice/exclude-from-ledger
|
||||||
|
:invoice/outstanding-balance
|
||||||
|
:invoice/date
|
||||||
|
{:invoice/vendor [:db/id :vendor/name]
|
||||||
|
:invoice/client [:db/id :client/code]
|
||||||
|
:invoice/payment [:db/id {:payment/status [:db/ident]}]
|
||||||
|
:invoice/status [:db/ident]
|
||||||
|
:invoice/import-status [:db/ident]
|
||||||
|
:invoice/expense-accounts [:invoice-expense-account/account
|
||||||
|
:invoice-expense-account/amount
|
||||||
|
:invoice-expense-account/location]}]
|
||||||
|
invoice-id)
|
||||||
|
credit-invoice? (< (:invoice/total entity 0.0) 0.0)]
|
||||||
|
(when-not (or
|
||||||
|
(not (:invoice/total entity))
|
||||||
|
(= true (:invoice/exclude-from-ledger entity))
|
||||||
|
(= :import-status/pending (:db/ident (:invoice/import-status entity)))
|
||||||
|
(= :invoice-status/voided (:db/ident (:invoice/status entity)))
|
||||||
|
(< -0.001 (:invoice/total entity) 0.001))
|
||||||
|
|
||||||
|
(-remove-nils
|
||||||
|
{:journal-entry/source "invoice"
|
||||||
|
:journal-entry/client (:db/id (:invoice/client entity))
|
||||||
|
:journal-entry/date (:invoice/date entity)
|
||||||
|
:journal-entry/original-entity raw-invoice-id
|
||||||
|
:journal-entry/vendor (:db/id (:invoice/vendor entity))
|
||||||
|
:journal-entry/amount (Math/abs (:invoice/total entity))
|
||||||
|
|
||||||
|
:journal-entry/line-items (into [(cond-> {:db/id (str raw-invoice-id "-" 0)
|
||||||
|
:journal-entry-line/account :account/accounts-payable
|
||||||
|
:journal-entry-line/location "A"
|
||||||
|
}
|
||||||
|
credit-invoice? (assoc :journal-entry-line/debit (Math/abs (:invoice/total entity)))
|
||||||
|
(not credit-invoice?) (assoc :journal-entry-line/credit (Math/abs (:invoice/total entity))))]
|
||||||
|
(map-indexed (fn [i ea]
|
||||||
|
(cond->
|
||||||
|
{:db/id (str raw-invoice-id "-" (inc i))
|
||||||
|
:journal-entry-line/account (:db/id (:invoice-expense-account/account ea))
|
||||||
|
:journal-entry-line/location (or (:invoice-expense-account/location ea) "HQ")
|
||||||
|
}
|
||||||
|
credit-invoice? (assoc :journal-entry-line/credit (Math/abs (:invoice-expense-account/amount ea)))
|
||||||
|
(not credit-invoice?) (assoc :journal-entry-line/debit (Math/abs (:invoice-expense-account/amount ea)))))
|
||||||
|
(:invoice/expense-accounts entity)))
|
||||||
|
:journal-entry/cleared (and (< (:invoice/outstanding-balance entity) 0.01)
|
||||||
|
(every? #(= :payment-status/cleared (:payment/status %)) (:invoice/payments entity))
|
||||||
|
)})))
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
|
(defn upsert-invoice [db invoice]
|
||||||
|
(let [upserted-entity [[:upsert-entity invoice]]
|
||||||
|
with-invoice (dc/with db upserted-entity)
|
||||||
|
invoice-id (or (-> with-invoice :tempids (get (:db/id invoice)))
|
||||||
|
(:db/id invoice))
|
||||||
|
journal-entry (invoice->journal-entry (:db-after with-invoice)
|
||||||
|
invoice-id
|
||||||
|
(:db/id invoice))]
|
||||||
|
(into upserted-entity
|
||||||
|
(if journal-entry
|
||||||
|
[[:upsert-ledger journal-entry]]
|
||||||
|
[[:db/retractEntity [:journal-entry/original-entity (:db/id invoice)]]]))))
|
||||||
71
iol_ion/src/iol_ion/tx/upsert_ledger.clj
Normal file
71
iol_ion/src/iol_ion/tx/upsert_ledger.clj
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
(ns iol-ion.tx.upsert-ledger
|
||||||
|
(:import [java.util UUID])
|
||||||
|
(:require [datomic.api :as dc]))
|
||||||
|
|
||||||
|
(defn -random-tempid []
|
||||||
|
(str (UUID/randomUUID)))
|
||||||
|
|
||||||
|
(defn get-line-items-after [db journal-entry]
|
||||||
|
(for [jel (:journal-entry/line-items journal-entry)
|
||||||
|
:let [next-jel (->> (dc/index-pull db {:index :avet
|
||||||
|
:selector [:db/id :journal-entry-line/client+account+location+date]
|
||||||
|
:start [:journal-entry-line/client+account+location+date
|
||||||
|
(:journal-entry-line/client+account+location+date jel)
|
||||||
|
(:db/id jel)]
|
||||||
|
:limit 3
|
||||||
|
})
|
||||||
|
(filter (fn line-must-match-client-account-location [result]
|
||||||
|
(and
|
||||||
|
(= (take 3 (:journal-entry-line/client+account+location+date result))
|
||||||
|
(take 3 (:journal-entry-line/client+account+location+date jel)))
|
||||||
|
(not= (:db/id jel)
|
||||||
|
(:db/id result)))
|
||||||
|
))
|
||||||
|
first
|
||||||
|
:db/id)]
|
||||||
|
:when next-jel]
|
||||||
|
next-jel))
|
||||||
|
|
||||||
|
(def extant-read '[:db/id :journal-entry/date :journal-entry/client {:journal-entry/line-items [:journal-entry-line/account :journal-entry-line/location :db/id :journal-entry-line/client+account+location+date]}])
|
||||||
|
|
||||||
|
|
||||||
|
(defn calc-client+account+location+date [je jel]
|
||||||
|
[(or
|
||||||
|
(:db/id (:journal-entry/client je))
|
||||||
|
(:journal-entry/client je))
|
||||||
|
(or (:db/id (:journal-entry-line/account jel))
|
||||||
|
(:journal-entry-line/account jel))
|
||||||
|
(-> jel :journal-entry-line/location)
|
||||||
|
(-> je :journal-entry/date)])
|
||||||
|
|
||||||
|
(defn upsert-ledger [db ledger-entry]
|
||||||
|
(assert (:journal-entry/date ledger-entry) "Must at least provide date when updating ledger")
|
||||||
|
(assert (:journal-entry/client ledger-entry) "Must at least provide client when updating ledger")
|
||||||
|
;; TODO these are not always true
|
||||||
|
;; (assert (every? :journal-entry-line/account (:journal-entry/line-items ledger-entry)) "must at least provide account when updating ledger")
|
||||||
|
;; (assert (every? :journal-entry-line/location (:journal-entry/line-items ledger-entry)) "Must at least provide location when updating ledger")
|
||||||
|
(let [extant-entry (or (when-let [original-entity (:journal-entry/original-entity ledger-entry)]
|
||||||
|
(dc/pull db extant-read [:journal-entry/original-entity original-entity]))
|
||||||
|
(when-let [external-id (:journal-entry/external-id ledger-entry)]
|
||||||
|
(dc/pull db extant-read [:journal-entry/external-id external-id])))
|
||||||
|
extant-entry-exists? (:db/id extant-entry)]
|
||||||
|
|
||||||
|
(cond->
|
||||||
|
[[:upsert-entity (into (-> ledger-entry
|
||||||
|
(assoc :db/id (or
|
||||||
|
(:db/id ledger-entry)
|
||||||
|
(:db/id extant-entry)
|
||||||
|
(-random-tempid)))
|
||||||
|
(update :journal-entry/line-items
|
||||||
|
(fn [lis]
|
||||||
|
(mapv #(-> %
|
||||||
|
(assoc :journal-entry-line/dirty true)
|
||||||
|
(assoc :journal-entry-line/client+account+location+date
|
||||||
|
(calc-client+account+location+date ledger-entry %)))
|
||||||
|
lis))))
|
||||||
|
)]]
|
||||||
|
extant-entry-exists? (into (map (fn [li]
|
||||||
|
{:journal-entry-line/dirty true
|
||||||
|
:db/id li})
|
||||||
|
(get-line-items-after db extant-entry))))))
|
||||||
|
|
||||||
86
iol_ion/src/iol_ion/tx/upsert_transaction.clj
Normal file
86
iol_ion/src/iol_ion/tx/upsert_transaction.clj
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
(ns iol-ion.tx.upsert-transaction
|
||||||
|
(:require [datomic.api :as dc]))
|
||||||
|
|
||||||
|
(defn -remove-nils [m]
|
||||||
|
(let [result (reduce-kv
|
||||||
|
(fn [m k v]
|
||||||
|
(if (not (nil? v))
|
||||||
|
(assoc m k v)
|
||||||
|
m
|
||||||
|
))
|
||||||
|
{}
|
||||||
|
m)]
|
||||||
|
(if (seq result)
|
||||||
|
result
|
||||||
|
nil)))
|
||||||
|
|
||||||
|
(defn transaction->journal-entry
|
||||||
|
[db transaction-id raw-transaction-id]
|
||||||
|
(let [entity (dc/pull db [:transaction/client
|
||||||
|
:transaction/date
|
||||||
|
:transaction/description-original
|
||||||
|
:db/id
|
||||||
|
:transaction/vendor
|
||||||
|
:transaction/amount
|
||||||
|
:transaction/cleared-against
|
||||||
|
{:transaction/accounts [:transaction-account/account
|
||||||
|
:transaction-account/location
|
||||||
|
:transaction-account/amount]
|
||||||
|
:transaction/approval-status [:db/ident]
|
||||||
|
:transaction/bank-account [:db/id {:bank-account/type [:db/ident]}]}]
|
||||||
|
transaction-id)
|
||||||
|
decreasing? (< (or (:transaction/amount entity) 0.0) 0.0)
|
||||||
|
credit-from-bank? decreasing?
|
||||||
|
debit-from-bank? (not decreasing?)]
|
||||||
|
(when (and (not (= :transaction-approval-status/excluded (:db/ident (:transaction/approval-status entity))))
|
||||||
|
(not (= :transaction-approval-status/suppressed (:db/ident (:transaction/approval-status entity))))
|
||||||
|
(:transaction/amount entity)
|
||||||
|
(not (< -0.001 (:transaction/amount entity) 0.001)))
|
||||||
|
(-remove-nils
|
||||||
|
{:journal-entry/source "transaction"
|
||||||
|
:journal-entry/client (:db/id (:transaction/client entity))
|
||||||
|
:journal-entry/date (:transaction/date entity)
|
||||||
|
:journal-entry/original-entity raw-transaction-id
|
||||||
|
:journal-entry/alternate-description (:transaction/description-original entity)
|
||||||
|
:journal-entry/vendor (:db/id (:transaction/vendor entity))
|
||||||
|
:journal-entry/amount (Math/abs (:transaction/amount entity))
|
||||||
|
:journal-entry/cleared-against (:transaction/cleared-against entity)
|
||||||
|
|
||||||
|
:journal-entry/line-items (into [(-remove-nils {:journal-entry-line/account (:db/id (:transaction/bank-account entity))
|
||||||
|
:db/id (str raw-transaction-id "-" 0)
|
||||||
|
:journal-entry-line/location "A"
|
||||||
|
:journal-entry-line/credit (when credit-from-bank?
|
||||||
|
(Math/abs (:transaction/amount entity)))
|
||||||
|
:journal-entry-line/debit (when debit-from-bank?
|
||||||
|
(Math/abs (:transaction/amount entity)))})
|
||||||
|
]
|
||||||
|
(map-indexed
|
||||||
|
(fn [i a]
|
||||||
|
(-remove-nils{
|
||||||
|
:db/id (str raw-transaction-id "-" (inc i))
|
||||||
|
:journal-entry-line/account (:db/id (:transaction-account/account a))
|
||||||
|
:journal-entry-line/location (:transaction-account/location a)
|
||||||
|
:journal-entry-line/debit (when credit-from-bank?
|
||||||
|
(Math/abs (:transaction-account/amount a)))
|
||||||
|
:journal-entry-line/credit (when debit-from-bank?
|
||||||
|
(Math/abs (:transaction-account/amount a)))}))
|
||||||
|
(if (seq (:transaction/accounts entity))
|
||||||
|
(:transaction/accounts entity)
|
||||||
|
[{:transaction-account/amount (:transaction/amount entity)}])))
|
||||||
|
|
||||||
|
:journal-entry/cleared true}))))
|
||||||
|
|
||||||
|
(defn upsert-transaction [db transaction]
|
||||||
|
;; because some transactions will reference temp ids, you have to dissoc them, like :transaction/payment
|
||||||
|
(let [upserted-entity [[:upsert-entity (dissoc transaction :transaction/payment :import-batch/_entry)]]
|
||||||
|
with-transaction (dc/with db upserted-entity)
|
||||||
|
transaction-id (or (-> with-transaction :tempids (get (:db/id transaction)))
|
||||||
|
(:db/id transaction))
|
||||||
|
journal-entry (transaction->journal-entry (:db-after with-transaction)
|
||||||
|
transaction-id
|
||||||
|
(:db/id transaction))]
|
||||||
|
(into [[:upsert-entity transaction]]
|
||||||
|
(if journal-entry
|
||||||
|
[[:upsert-ledger journal-entry]]
|
||||||
|
[[:db/retractEntity [:journal-entry/original-entity (:db/id transaction)]]]))))
|
||||||
|
|
||||||
36
iol_ion/src/iol_ion/utils.clj
Normal file
36
iol_ion/src/iol_ion/utils.clj
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
(ns iol-ion.utils
|
||||||
|
(:require [datomic.api :as dc])
|
||||||
|
(:import [java.util UUID]))
|
||||||
|
|
||||||
|
(defn random-tempid []
|
||||||
|
(str (UUID/randomUUID)))
|
||||||
|
|
||||||
|
(defn by
|
||||||
|
([f xs]
|
||||||
|
(by f identity xs))
|
||||||
|
([f fv xs]
|
||||||
|
(reduce
|
||||||
|
#(assoc %1 (f %2) (fv %2))
|
||||||
|
{}
|
||||||
|
xs)))
|
||||||
|
|
||||||
|
(defn pull-many [db read ids ]
|
||||||
|
(->> (dc/q '[:find (pull ?e r)
|
||||||
|
:in $ [?e ...] r]
|
||||||
|
db
|
||||||
|
ids
|
||||||
|
read)
|
||||||
|
(map first)))
|
||||||
|
|
||||||
|
(defn remove-nils [m]
|
||||||
|
(let [result (reduce-kv
|
||||||
|
(fn [m k v]
|
||||||
|
(if (not (nil? v))
|
||||||
|
(assoc m k v)
|
||||||
|
m
|
||||||
|
))
|
||||||
|
{}
|
||||||
|
m)]
|
||||||
|
(if (seq result)
|
||||||
|
result
|
||||||
|
nil)))
|
||||||
10
project.clj
10
project.clj
@@ -2,17 +2,13 @@
|
|||||||
:description "FIXME: write description"
|
:description "FIXME: write description"
|
||||||
:url "http://example.com/FIXME"
|
:url "http://example.com/FIXME"
|
||||||
:min-lein-version "2.0.0"
|
:min-lein-version "2.0.0"
|
||||||
:repositories {"my.datomic.com" {:url "https://my.datomic.com/repo"
|
|
||||||
:username "datomic@brycecovertoperations.com"
|
|
||||||
:password "9a382afc-d119-44db-83c2-98d8057d7666"}}
|
|
||||||
|
|
||||||
:dependencies [[com.google.guava/guava "31.1-jre"]
|
:dependencies [[com.google.guava/guava "31.1-jre"]
|
||||||
[org.clojure/clojure "1.10.1"]
|
[org.clojure/clojure "1.10.1"]
|
||||||
[com.unbounce/clojure-dogstatsd-client "0.7.0"]
|
[com.unbounce/clojure-dogstatsd-client "0.7.0"]
|
||||||
[org.clojure/tools.reader "1.3.6"]
|
[org.clojure/tools.reader "1.3.6"]
|
||||||
[com.cognitect/hmac-authn "0.1.210"]
|
[com.cognitect/hmac-authn "0.1.210"]
|
||||||
[com.datomic/client-cloud "1.0.123"]
|
[com.github.ivarref/gen-fn "0.2.46"]
|
||||||
[com.cognitect/http-client "1.0.115"]
|
[com.datomic/peer "1.0.6726"]
|
||||||
[lambdaisland/edn-lines "1.0.10"]
|
[lambdaisland/edn-lines "1.0.10"]
|
||||||
[bidi "2.1.6"]
|
[bidi "2.1.6"]
|
||||||
[ring/ring-defaults "0.3.2" :exclusions [ring ring/ring-core]]
|
[ring/ring-defaults "0.3.2" :exclusions [ring ring/ring-core]]
|
||||||
@@ -131,7 +127,7 @@
|
|||||||
:dependencies [#_[binaryage/devteols "1.0.2"]
|
:dependencies [#_[binaryage/devteols "1.0.2"]
|
||||||
[postgresql/postgresql "9.3-1102.jdbc41"]
|
[postgresql/postgresql "9.3-1102.jdbc41"]
|
||||||
[org.clojure/java.jdbc "0.7.11"]
|
[org.clojure/java.jdbc "0.7.11"]
|
||||||
[com.datomic/dev-local "1.0.243"]
|
#_[com.datomic/dev-local "1.0.243"]
|
||||||
[etaoin "0.4.1"]
|
[etaoin "0.4.1"]
|
||||||
[com.bhauman/figwheel-main "0.2.18" :exclusions [org.clojure/clojurescript
|
[com.bhauman/figwheel-main "0.2.18" :exclusions [org.clojure/clojurescript
|
||||||
ring
|
ring
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
}
|
}
|
||||||
{:db/valueType :db.type/tuple
|
{:db/valueType :db.type/tuple
|
||||||
:db/tupleTypes [:db.type/ref :db.type/ref :db.type/string :db.type/instant]
|
:db/tupleTypes [:db.type/ref :db.type/ref :db.type/string :db.type/instant]
|
||||||
|
:db/index true
|
||||||
:db/cardinality :db.cardinality/one,
|
:db/cardinality :db.cardinality/one,
|
||||||
:db/ident :journal-entry-line/client+account+location+date
|
:db/ident :journal-entry-line/client+account+location+date
|
||||||
:db/doc "Used to find accounts and locations quickly",
|
:db/doc "Used to find accounts and locations quickly",
|
||||||
@@ -20,6 +21,7 @@
|
|||||||
|
|
||||||
{:db/valueType :db.type/tuple
|
{:db/valueType :db.type/tuple
|
||||||
:db/tupleAttrs [:sales-order/client :sales-order/date]
|
:db/tupleAttrs [:sales-order/client :sales-order/date]
|
||||||
|
:db/index true
|
||||||
:db/cardinality :db.cardinality/one,
|
:db/cardinality :db.cardinality/one,
|
||||||
:db/ident :sales-order/client+date
|
:db/ident :sales-order/client+date
|
||||||
:db/doc "Used to find sales orders quickly",
|
:db/doc "Used to find sales orders quickly",
|
||||||
|
|||||||
@@ -1,10 +1,20 @@
|
|||||||
(ns auto-ap.datomic
|
(ns auto-ap.datomic
|
||||||
(:require
|
(:require
|
||||||
|
[iol-ion.tx.pay]
|
||||||
|
[iol-ion.tx.plus]
|
||||||
|
[iol-ion.tx.propose-invoice]
|
||||||
|
[iol-ion.tx.reset-rels]
|
||||||
|
[iol-ion.tx.reset-scalars]
|
||||||
|
[iol-ion.tx.upsert-entity]
|
||||||
|
[iol-ion.tx.upsert-invoice]
|
||||||
|
[iol-ion.tx.upsert-ledger]
|
||||||
|
[iol-ion.tx.upsert-transaction]
|
||||||
|
[com.github.ivarref.gen-fn :refer [gen-fn! datomic-fn]]
|
||||||
[auto-ap.utils :refer [default-pagination-size by]]
|
[auto-ap.utils :refer [default-pagination-size by]]
|
||||||
[clojure.tools.logging :as log]
|
[clojure.tools.logging :as log]
|
||||||
[clojure.edn :as edn]
|
[clojure.edn :as edn]
|
||||||
[config.core :refer [env]]
|
[config.core :refer [env]]
|
||||||
[datomic.client.api :as dc]
|
[datomic.api :as dc]
|
||||||
[com.brunobonacci.mulog :as mu]
|
[com.brunobonacci.mulog :as mu]
|
||||||
[mount.core :as mount]
|
[mount.core :as mount]
|
||||||
[clojure.java.io :as io])
|
[clojure.java.io :as io])
|
||||||
@@ -13,12 +23,12 @@
|
|||||||
|
|
||||||
(def uri (:datomic-url env))
|
(def uri (:datomic-url env))
|
||||||
|
|
||||||
(mount/defstate client
|
#_(mount/defstate client
|
||||||
:start (dc/client (:client-config env))
|
:start (dc/client (:client-config env))
|
||||||
:stop nil)
|
:stop nil)
|
||||||
|
|
||||||
(mount/defstate conn
|
(mount/defstate conn
|
||||||
:start (dc/connect client {:db-name (:db-name env)})
|
:start (dc/connect "datomic:ddb://us-east-1/iol-dev/dev")
|
||||||
:stop nil)
|
:stop nil)
|
||||||
|
|
||||||
#_(def uri "datomic:mem://datomic-transactor:4334/invoice")
|
#_(def uri "datomic:mem://datomic-transactor:4334/invoice")
|
||||||
@@ -627,7 +637,7 @@
|
|||||||
_ (mu/log ::transacting-batch
|
_ (mu/log ::transacting-batch
|
||||||
:batch batch-id
|
:batch batch-id
|
||||||
:count (count batch))
|
:count (count batch))
|
||||||
tx-result (dc/transact conn {:tx-data batch})]
|
tx-result @(dc/transact conn batch)]
|
||||||
|
|
||||||
(cond-> full-tx
|
(cond-> full-tx
|
||||||
(:tx-data full-tx) (update :tx-data #(into % (:tx-data tx-result)))
|
(:tx-data full-tx) (update :tx-data #(into % (:tx-data tx-result)))
|
||||||
@@ -641,8 +651,8 @@
|
|||||||
|
|
||||||
(defn audit-transact [txes id]
|
(defn audit-transact [txes id]
|
||||||
(try
|
(try
|
||||||
(dc/transact conn {:tx-data (conj txes {:db/id "datomic.tx"
|
@(dc/transact conn (conj txes {:db/id "datomic.tx"
|
||||||
:audit/user (str (:user/role id) "-" (:user/name id))})})
|
:audit/user (str (:user/role id) "-" (:user/name id))}))
|
||||||
(catch Exception e
|
(catch Exception e
|
||||||
(mu/log ::transaction-error
|
(mu/log ::transaction-error
|
||||||
:exception e
|
:exception e
|
||||||
@@ -821,15 +831,24 @@
|
|||||||
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
(defn install-functions []
|
||||||
|
@(datomic.api/transact auto-ap.datomic/conn [(datomic-fn :pay #'iol-ion.tx.pay/pay)
|
||||||
|
(datomic-fn :plus #'iol-ion.tx.plus/plus)
|
||||||
|
(datomic-fn :propose-invoice #'iol-ion.tx.propose-invoice/propose-invoice)
|
||||||
|
(datomic-fn :reset-rels #'iol-ion.tx.reset-rels/reset-rels)
|
||||||
|
(datomic-fn :reset-scalars #'iol-ion.tx.reset-scalars/reset-scalars)
|
||||||
|
(datomic-fn :upsert-entity #'iol-ion.tx.upsert-entity/upsert-entity)
|
||||||
|
(datomic-fn :upsert-invoice #'iol-ion.tx.upsert-invoice/upsert-invoice)
|
||||||
|
(datomic-fn :upsert-ledger #'iol-ion.tx.upsert-ledger/upsert-ledger)
|
||||||
|
(datomic-fn :upsert-transaction #'iol-ion.tx.upsert-transaction/upsert-transaction)]))
|
||||||
|
|
||||||
(defn transact-schema [conn]
|
(defn transact-schema [conn]
|
||||||
(dc/transact conn
|
@(dc/transact conn
|
||||||
{:tx-data (edn/read-string (slurp (io/resource "schema.edn")))})
|
(edn/read-string (slurp (io/resource "schema.edn"))))
|
||||||
|
|
||||||
;; this is temporary for any new stuff that needs to be asserted for cloud migration.
|
;; this is temporary for any new stuff that needs to be asserted for cloud migration.
|
||||||
(dc/transact conn
|
@(dc/transact conn
|
||||||
{:tx-data (edn/read-string (slurp (io/resource "cloud-migration-schema.edn")))}))
|
(edn/read-string (slurp (io/resource "cloud-migration-schema.edn")))))
|
||||||
|
|
||||||
(defn backoff [n]
|
(defn backoff [n]
|
||||||
(let [base-timeout 500
|
(let [base-timeout 500
|
||||||
@@ -842,7 +861,7 @@
|
|||||||
([tx ] (transact-with-backoff tx 0))
|
([tx ] (transact-with-backoff tx 0))
|
||||||
([tx attempt]
|
([tx attempt]
|
||||||
(try
|
(try
|
||||||
(dc/transact conn {:tx-data tx})
|
@(dc/transact conn tx)
|
||||||
(catch Exception e
|
(catch Exception e
|
||||||
(if (< attempt 10)
|
(if (< attempt 10)
|
||||||
(do
|
(do
|
||||||
@@ -870,3 +889,8 @@
|
|||||||
(#{"manager" "user" "power-user"} (:user/role id))
|
(#{"manager" "user" "power-user"} (:user/role id))
|
||||||
(into #{}
|
(into #{}
|
||||||
(map :db/id (:user/clients id [])))))
|
(map :db/id (:user/clients id [])))))
|
||||||
|
|
||||||
|
|
||||||
|
(defn query2 [query]
|
||||||
|
(apply dc/q (:query query) (:args query)))
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,16 @@
|
|||||||
(ns auto-ap.datomic.accounts
|
(ns auto-ap.datomic.accounts
|
||||||
(:require
|
(:require
|
||||||
[auto-ap.datomic
|
[auto-ap.datomic
|
||||||
:refer [add-sorter-fields apply-pagination apply-sort-3 conn merge-query conn pull-many]]
|
:refer [add-sorter-fields
|
||||||
|
apply-pagination
|
||||||
|
apply-sort-3
|
||||||
|
conn
|
||||||
|
merge-query
|
||||||
|
pull-many
|
||||||
|
query2]]
|
||||||
[clojure.string :as str]
|
[clojure.string :as str]
|
||||||
[datomic.client.api :as dc]
|
[clojure.tools.logging :as log]
|
||||||
[clojure.tools.logging :as log]))
|
[datomic.api :as dc]))
|
||||||
|
|
||||||
(defn <-datomic [a]
|
(defn <-datomic [a]
|
||||||
(-> a
|
(-> a
|
||||||
@@ -42,19 +48,19 @@
|
|||||||
:where [['?e :account/account-set '?account-set]]}
|
:where [['?e :account/account-set '?account-set]]}
|
||||||
:args [(:account-set args)]}))]
|
:args [(:account-set args)]}))]
|
||||||
(->>
|
(->>
|
||||||
(dc/q query)
|
(query2 query)
|
||||||
(map first)
|
(map first)
|
||||||
(map <-datomic)))))
|
(map <-datomic)))))
|
||||||
|
|
||||||
(defn get-by-id [id]
|
(defn get-by-id [id]
|
||||||
(let [query {:query {:find [(list 'pull '?e default-read)]
|
|
||||||
:in ['$ '?e]}
|
|
||||||
:args [(dc/db conn ) id]}]
|
|
||||||
(->>
|
(->>
|
||||||
(dc/q query)
|
(dc/q {:find [(list 'pull '?e default-read)]
|
||||||
|
:in ['$ '?e]}
|
||||||
|
(dc/db conn )
|
||||||
|
id)
|
||||||
(map first)
|
(map first)
|
||||||
(map <-datomic)
|
(map <-datomic)
|
||||||
first)))
|
first))
|
||||||
|
|
||||||
(defn get-for-vendor [vendor-id client-id]
|
(defn get-for-vendor [vendor-id client-id]
|
||||||
(if client-id
|
(if client-id
|
||||||
@@ -87,15 +93,14 @@
|
|||||||
default-read))))
|
default-read))))
|
||||||
|
|
||||||
(defn get-account-by-numeric-code-and-sets [numeric-code _]
|
(defn get-account-by-numeric-code-and-sets [numeric-code _]
|
||||||
(let [query (cond-> {:query {:find ['(pull ?e [* {:account/type [:db/ident :db/id]}])]
|
(->>
|
||||||
|
(dc/q {:find ['(pull ?e [* {:account/type [:db/ident :db/id]}])]
|
||||||
:in ['$ '?numeric-code]
|
:in ['$ '?numeric-code]
|
||||||
:where ['[?e :account/numeric-code ?numeric-code]]}
|
:where ['[?e :account/numeric-code ?numeric-code]]}
|
||||||
:args [(dc/db conn) numeric-code]})]
|
(dc/db conn) numeric-code)
|
||||||
(->>
|
|
||||||
(dc/q query)
|
|
||||||
(map first)
|
(map first)
|
||||||
(map <-datomic)
|
(map <-datomic)
|
||||||
(first))))
|
(first)))
|
||||||
|
|
||||||
(defn raw-graphql-ids [db args]
|
(defn raw-graphql-ids [db args]
|
||||||
(let [query (cond-> {:query {:find []
|
(let [query (cond-> {:query {:find []
|
||||||
@@ -122,8 +127,7 @@
|
|||||||
'[?e :account/numeric-code ?sort-default]]}}))]
|
'[?e :account/numeric-code ?sort-default]]}}))]
|
||||||
|
|
||||||
|
|
||||||
(cond->> query
|
(cond->> (query2 query)
|
||||||
true (dc/q)
|
|
||||||
true (apply-sort-3 args)
|
true (apply-sort-3 args)
|
||||||
true (apply-pagination args))))
|
true (apply-pagination args))))
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
(ns auto-ap.datomic.bank-accounts
|
(ns auto-ap.datomic.bank-accounts
|
||||||
(:require
|
(:require
|
||||||
[auto-ap.datomic :refer [conn]]
|
[auto-ap.datomic :refer [conn]]
|
||||||
[datomic.client.api :as dc]))
|
[datomic.api :as dc]))
|
||||||
|
|
||||||
(defn add-arg [query name value where & rest]
|
(defn add-arg [query name value where & rest]
|
||||||
(let [query (-> query
|
(let [query (-> query
|
||||||
@@ -20,13 +20,7 @@
|
|||||||
|
|
||||||
|
|
||||||
(defn get-by-id [id]
|
(defn get-by-id [id]
|
||||||
(->>
|
(->> [(dc/pull (dc/db conn default-read id))]
|
||||||
(dc/q (-> {:query {:find [default-read]
|
|
||||||
:in ['$]
|
|
||||||
:where []}
|
|
||||||
:args [(dc/db conn)]}
|
|
||||||
(add-arg '?e id ['?e])))
|
|
||||||
(map first)
|
|
||||||
(<-datomic)
|
(<-datomic)
|
||||||
(first)))
|
(first)))
|
||||||
|
|
||||||
|
|||||||
@@ -6,12 +6,13 @@
|
|||||||
apply-sort-3
|
apply-sort-3
|
||||||
conn
|
conn
|
||||||
merge-query
|
merge-query
|
||||||
pull-many]]
|
pull-many
|
||||||
|
query2]]
|
||||||
[auto-ap.graphql.utils :refer [limited-clients]]
|
[auto-ap.graphql.utils :refer [limited-clients]]
|
||||||
[clj-time.coerce :as c]
|
[clj-time.coerce :as c]
|
||||||
[datomic.client.api :as dc]
|
|
||||||
[clojure.set :refer [rename-keys]]
|
[clojure.set :refer [rename-keys]]
|
||||||
[clojure.tools.logging :as log]))
|
[clojure.tools.logging :as log]
|
||||||
|
[datomic.api :as dc]))
|
||||||
|
|
||||||
(defn <-datomic [result]
|
(defn <-datomic [result]
|
||||||
(-> result
|
(-> result
|
||||||
@@ -154,8 +155,7 @@
|
|||||||
|
|
||||||
|
|
||||||
(log/info query)
|
(log/info query)
|
||||||
(cond->> query
|
(cond->> (query2 query)
|
||||||
true (dc/q)
|
|
||||||
true (apply-sort-3 (assoc args :default-asc? false))
|
true (apply-sort-3 (assoc args :default-asc? false))
|
||||||
true (apply-pagination args)))))
|
true (apply-pagination args)))))
|
||||||
|
|
||||||
@@ -178,11 +178,10 @@
|
|||||||
|
|
||||||
(defn filter-ids [ids]
|
(defn filter-ids [ids]
|
||||||
(if ids
|
(if ids
|
||||||
(->> {:query {:find ['?e]
|
(->> (dc/q {:find ['?e]
|
||||||
:in ['$ '[?e ...]]
|
:in ['$ '[?e ...]]
|
||||||
:where ['[?e :payment/date]]}
|
:where ['[?e :payment/date]]}
|
||||||
:args [(dc/db conn) ids]}
|
(dc/db conn) ids)
|
||||||
(dc/q)
|
|
||||||
(map first)
|
(map first)
|
||||||
vec)
|
vec)
|
||||||
[]))
|
[]))
|
||||||
|
|||||||
@@ -1,17 +1,19 @@
|
|||||||
(ns auto-ap.datomic.clients
|
(ns auto-ap.datomic.clients
|
||||||
(:require
|
(:require
|
||||||
[auto-ap.datomic :refer [add-sorter-fields
|
[auto-ap.datomic
|
||||||
|
:refer [add-sorter-fields
|
||||||
apply-pagination
|
apply-pagination
|
||||||
apply-sort-3
|
apply-sort-3
|
||||||
conn
|
conn
|
||||||
merge-query
|
merge-query
|
||||||
pull-many]]
|
pull-many
|
||||||
[auto-ap.graphql.utils :refer [can-see-client? limited-clients]]
|
query2]]
|
||||||
|
[auto-ap.graphql.utils :refer [limited-clients]]
|
||||||
[auto-ap.search :as search]
|
[auto-ap.search :as search]
|
||||||
[clj-time.coerce :as coerce]
|
[clj-time.coerce :as coerce]
|
||||||
[clojure.string :as str]
|
[clojure.string :as str]
|
||||||
[datomic.client.api :as dc]
|
[com.brunobonacci.mulog :as mu]
|
||||||
[com.brunobonacci.mulog :as mu]))
|
[datomic.api :as dc]))
|
||||||
|
|
||||||
(def full-read '[*
|
(def full-read '[*
|
||||||
{:client/square-integration-status [:integration-status/message
|
{:client/square-integration-status [:integration-status/message
|
||||||
@@ -97,10 +99,10 @@
|
|||||||
|
|
||||||
(defn code->id [code]
|
(defn code->id [code]
|
||||||
(->>
|
(->>
|
||||||
(dc/q (-> {:query {:find ['?e]
|
(dc/q (-> {:find ['?e]
|
||||||
:in ['$ '?code]
|
:in ['$ '?code]
|
||||||
:where [['?e :client/code '?code ]]}
|
:where [['?e :client/code '?code ]]}
|
||||||
:args [(dc/db conn) code]}))
|
(dc/db conn) code))
|
||||||
(first)
|
(first)
|
||||||
(first)))
|
(first)))
|
||||||
|
|
||||||
@@ -155,8 +157,7 @@
|
|||||||
(merge-query {:query {:find ['?sort-default '?e] :where ['[?e :client/name ?sort-default]]}}))]
|
(merge-query {:query {:find ['?sort-default '?e] :where ['[?e :client/name ?sort-default]]}}))]
|
||||||
(mu/log ::q
|
(mu/log ::q
|
||||||
:query query)
|
:query query)
|
||||||
(->> query
|
(->> (query2 query)
|
||||||
(dc/q)
|
|
||||||
(apply-sort-3 (update args :sort conj {:sort-key "default-2" :asc true}))
|
(apply-sort-3 (update args :sort conj {:sort-key "default-2" :asc true}))
|
||||||
(apply-pagination args))))
|
(apply-pagination args))))
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,16 @@
|
|||||||
(ns auto-ap.datomic.expected-deposit
|
(ns auto-ap.datomic.expected-deposit
|
||||||
(:require
|
(:require
|
||||||
[auto-ap.datomic
|
[auto-ap.datomic
|
||||||
:refer [add-sorter-fields apply-pagination apply-sort-3 conn merge-query pull-many]]
|
:refer [add-sorter-fields
|
||||||
|
apply-pagination
|
||||||
|
apply-sort-3
|
||||||
|
conn
|
||||||
|
merge-query
|
||||||
|
pull-many
|
||||||
|
query2]]
|
||||||
[auto-ap.graphql.utils :refer [limited-clients]]
|
[auto-ap.graphql.utils :refer [limited-clients]]
|
||||||
[clj-time.coerce :as c]
|
[clj-time.coerce :as c]
|
||||||
[datomic.client.api :as dc]))
|
[datomic.api :as dc]))
|
||||||
|
|
||||||
(defn <-datomic [result]
|
(defn <-datomic [result]
|
||||||
(let [transaction (first (:transaction/_expected-deposit result))
|
(let [transaction (first (:transaction/_expected-deposit result))
|
||||||
@@ -87,8 +93,7 @@
|
|||||||
(merge-query {:query {:find ['?sort-default '?e]
|
(merge-query {:query {:find ['?sort-default '?e]
|
||||||
:where ['[?e :expected-deposit/date ?sort-default]]}}))]
|
:where ['[?e :expected-deposit/date ?sort-default]]}}))]
|
||||||
|
|
||||||
(cond->> query
|
(cond->> (query2 query)
|
||||||
true (dc/q)
|
|
||||||
true (apply-sort-3 args)
|
true (apply-sort-3 args)
|
||||||
true (apply-pagination args))))
|
true (apply-pagination args))))
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
[auto-ap.datomic
|
[auto-ap.datomic
|
||||||
:refer [add-sorter-fields
|
:refer [add-sorter-fields
|
||||||
apply-pagination
|
apply-pagination
|
||||||
|
query2
|
||||||
apply-sort-3
|
apply-sort-3
|
||||||
conn
|
conn
|
||||||
merge-query
|
merge-query
|
||||||
@@ -14,7 +15,7 @@
|
|||||||
[clj-time.coerce :as coerce]
|
[clj-time.coerce :as coerce]
|
||||||
[clj-time.core :as time]
|
[clj-time.core :as time]
|
||||||
[clojure.set :refer [rename-keys]]
|
[clojure.set :refer [rename-keys]]
|
||||||
[datomic.client.api :as dc]
|
[datomic.api :as dc]
|
||||||
[iol-ion.tx :refer [random-tempid]]))
|
[iol-ion.tx :refer [random-tempid]]))
|
||||||
|
|
||||||
(def default-read '[*
|
(def default-read '[*
|
||||||
@@ -45,7 +46,7 @@
|
|||||||
([args]
|
([args]
|
||||||
(raw-graphql-ids (dc/db conn) args))
|
(raw-graphql-ids (dc/db conn) args))
|
||||||
([db args]
|
([db args]
|
||||||
(->> (cond-> {:query {:find []
|
(let [query (cond-> {:query {:find []
|
||||||
:in ['$]
|
:in ['$]
|
||||||
:where ['[?e :invoice/client]]}
|
:where ['[?e :invoice/client]]}
|
||||||
:args [db]}
|
:args [db]}
|
||||||
@@ -169,10 +170,10 @@
|
|||||||
true
|
true
|
||||||
(merge-query {:query {:find ['?sort-default '?e ]
|
(merge-query {:query {:find ['?sort-default '?e ]
|
||||||
:where ['[?e :invoice/client]
|
:where ['[?e :invoice/client]
|
||||||
'[?e :invoice/date ?sort-default]]}}) )
|
'[?e :invoice/date ?sort-default]]}}) )]
|
||||||
(dc/q)
|
(->> (query2 query)
|
||||||
(apply-sort-3 args)
|
(apply-sort-3 args)
|
||||||
(apply-pagination args))))
|
(apply-pagination args)))))
|
||||||
|
|
||||||
|
|
||||||
(defn graphql-results [ids db _]
|
(defn graphql-results [ids db _]
|
||||||
@@ -188,12 +189,11 @@
|
|||||||
(defn sum-outstanding [ids]
|
(defn sum-outstanding [ids]
|
||||||
|
|
||||||
(->>
|
(->>
|
||||||
(dc/q {:query {:find ['?id '?o]
|
(dc/q {:find ['?id '?o]
|
||||||
:in ['$ '[?id ...]]
|
:in ['$ '[?id ...]]
|
||||||
:where ['[?id :invoice/outstanding-balance ?o]]
|
:where ['[?id :invoice/outstanding-balance ?o]]}
|
||||||
}
|
(dc/db conn)
|
||||||
:args [(dc/db conn)
|
ids)
|
||||||
ids]})
|
|
||||||
(map last)
|
(map last)
|
||||||
(reduce
|
(reduce
|
||||||
+
|
+
|
||||||
@@ -202,12 +202,12 @@
|
|||||||
(defn sum-total-amount [ids]
|
(defn sum-total-amount [ids]
|
||||||
|
|
||||||
(->>
|
(->>
|
||||||
(dc/q {:query {:find ['?id '?o]
|
(dc/q {:find ['?id '?o]
|
||||||
:in ['$ '[?id ...]]
|
:in ['$ '[?id ...]]
|
||||||
:where ['[?id :invoice/total ?o]]
|
:where ['[?id :invoice/total ?o]]
|
||||||
}
|
}
|
||||||
:args [(dc/db conn)
|
(dc/db conn)
|
||||||
ids]})
|
ids)
|
||||||
(map last)
|
(map last)
|
||||||
(reduce
|
(reduce
|
||||||
+
|
+
|
||||||
@@ -240,38 +240,35 @@
|
|||||||
(defn find-conflicting [{:keys [:invoice/invoice-number :invoice/vendor :invoice/client :db/id]}]
|
(defn find-conflicting [{:keys [:invoice/invoice-number :invoice/vendor :invoice/client :db/id]}]
|
||||||
|
|
||||||
(->> (dc/q
|
(->> (dc/q
|
||||||
(cond-> {:query {:find [(list 'pull '?e default-read)]
|
{:find [(list 'pull '?e default-read)]
|
||||||
:in ['$ '?invoice-number '?vendor '?client '?invoice-id]
|
:in ['$ '?invoice-number '?vendor '?client '?invoice-id]
|
||||||
:where '[[?e :invoice/invoice-number ?invoice-number]
|
:where '[[?e :invoice/invoice-number ?invoice-number]
|
||||||
[?e :invoice/vendor ?vendor]
|
[?e :invoice/vendor ?vendor]
|
||||||
[?e :invoice/client ?client]
|
[?e :invoice/client ?client]
|
||||||
(not [?e :invoice/status :invoice-status/voided])
|
(not [?e :invoice/status :invoice-status/voided])
|
||||||
[(not= ?e ?invoice-id)]]}
|
[(not= ?e ?invoice-id)]]}
|
||||||
|
(dc/db conn) invoice-number vendor client (or id 0))
|
||||||
:args [(dc/db conn) invoice-number vendor client (or id 0)]}))
|
|
||||||
(map first)
|
(map first)
|
||||||
(map <-datomic)))
|
(map <-datomic)))
|
||||||
|
|
||||||
|
|
||||||
(defn get-existing-set []
|
(defn get-existing-set []
|
||||||
(let [vendored-results (set (dc/q {:query {:find ['?vendor '?client '?invoice-number]
|
(let [vendored-results (set (dc/q {:find ['?vendor '?client '?invoice-number]
|
||||||
:in ['$]
|
:in ['$]
|
||||||
:where '[[?e :invoice/invoice-number ?invoice-number]
|
:where '[[?e :invoice/invoice-number ?invoice-number]
|
||||||
[?e :invoice/vendor ?vendor]
|
[?e :invoice/vendor ?vendor]
|
||||||
[?e :invoice/client ?client]
|
[?e :invoice/client ?client]
|
||||||
(not [?e :invoice/status :invoice-status/voided])
|
(not [?e :invoice/status :invoice-status/voided])
|
||||||
]}
|
]}
|
||||||
|
(dc/db conn)))
|
||||||
:args [(dc/db conn)]}))
|
vendorless-results (->> (dc/q {:find ['?client '?invoice-number]
|
||||||
vendorless-results (->> (dc/q {:query {:find ['?client '?invoice-number]
|
|
||||||
:in ['$]
|
:in ['$]
|
||||||
:where '[[?e :invoice/invoice-number ?invoice-number]
|
:where '[[?e :invoice/invoice-number ?invoice-number]
|
||||||
(not [?e :invoice/vendor])
|
(not [?e :invoice/vendor])
|
||||||
[?e :invoice/client ?client]
|
[?e :invoice/client ?client]
|
||||||
(not [?e :invoice/status :invoice-status/voided])
|
(not [?e :invoice/status :invoice-status/voided])
|
||||||
]}
|
]}
|
||||||
|
(dc/db conn))
|
||||||
:args [(dc/db conn)]})
|
|
||||||
(mapv (fn [[client invoice-number]]
|
(mapv (fn [[client invoice-number]]
|
||||||
[nil client invoice-number]) )
|
[nil client invoice-number]) )
|
||||||
set)]
|
set)]
|
||||||
@@ -279,11 +276,11 @@
|
|||||||
|
|
||||||
(defn filter-ids [ids]
|
(defn filter-ids [ids]
|
||||||
(if ids
|
(if ids
|
||||||
(->> {:query {:find ['?e]
|
(->>
|
||||||
|
(dc/q {:find ['?e]
|
||||||
:in ['$ '[?e ...]]
|
:in ['$ '[?e ...]]
|
||||||
:where ['[?e :invoice/date]]}
|
:where ['[?e :invoice/date]]}
|
||||||
:args [(dc/db conn) ids]}
|
(dc/db conn) ids)
|
||||||
(dc/q)
|
|
||||||
(map first)
|
(map first)
|
||||||
vec)
|
vec)
|
||||||
[]))
|
[]))
|
||||||
|
|||||||
@@ -6,11 +6,12 @@
|
|||||||
apply-sort-3
|
apply-sort-3
|
||||||
conn
|
conn
|
||||||
merge-query
|
merge-query
|
||||||
pull-many]]
|
pull-many
|
||||||
|
query2]]
|
||||||
[auto-ap.datomic.accounts :as d-accounts]
|
[auto-ap.datomic.accounts :as d-accounts]
|
||||||
[auto-ap.graphql.utils :refer [limited-clients]]
|
[auto-ap.graphql.utils :refer [limited-clients]]
|
||||||
[clj-time.coerce :as c]
|
[clj-time.coerce :as c]
|
||||||
[datomic.client.api :as dc]))
|
[datomic.api :as dc]))
|
||||||
|
|
||||||
(defn raw-graphql-ids [db args]
|
(defn raw-graphql-ids [db args]
|
||||||
(let [query (cond-> {:query {:find []
|
(let [query (cond-> {:query {:find []
|
||||||
@@ -126,8 +127,7 @@
|
|||||||
|
|
||||||
true
|
true
|
||||||
(merge-query {:query {:find ['?sort-default '?e] :where ['[?e :journal-entry/date ?sort-default]]}}))]
|
(merge-query {:query {:find ['?sort-default '?e] :where ['[?e :journal-entry/date ?sort-default]]}}))]
|
||||||
(->> query
|
(->> (query2 query)
|
||||||
(dc/q)
|
|
||||||
(apply-sort-3 (update args :sort conj {:sort-key "default-2" :asc true}))
|
(apply-sort-3 (update args :sort conj {:sort-key "default-2" :asc true}))
|
||||||
(apply-pagination args))))
|
(apply-pagination args))))
|
||||||
|
|
||||||
@@ -168,11 +168,10 @@
|
|||||||
|
|
||||||
(defn filter-ids [ids]
|
(defn filter-ids [ids]
|
||||||
(if ids
|
(if ids
|
||||||
(->> {:query {:find ['?e]
|
(->> (dc/q {:find ['?e]
|
||||||
:in ['$ '[?e ...]]
|
:in ['$ '[?e ...]]
|
||||||
:where ['[?e :journal-entry/date]]}
|
:where ['[?e :journal-entry/date]]}
|
||||||
:args [(dc/db conn) ids]}
|
(dc/db conn) ids)
|
||||||
(dc/q)
|
|
||||||
(map first)
|
(map first)
|
||||||
vec)
|
vec)
|
||||||
[]))
|
[]))
|
||||||
|
|||||||
@@ -6,10 +6,11 @@
|
|||||||
apply-sort-3
|
apply-sort-3
|
||||||
conn
|
conn
|
||||||
merge-query
|
merge-query
|
||||||
pull-many]]
|
pull-many
|
||||||
|
query2]]
|
||||||
[auto-ap.graphql.utils :refer [can-see-client? limited-clients]]
|
[auto-ap.graphql.utils :refer [can-see-client? limited-clients]]
|
||||||
[clj-time.coerce :as c]
|
[clj-time.coerce :as c]
|
||||||
[datomic.client.api :as dc]))
|
[datomic.api :as dc]))
|
||||||
|
|
||||||
(defn raw-graphql-ids [db args]
|
(defn raw-graphql-ids [db args]
|
||||||
(let [query (cond-> {:query {:find []
|
(let [query (cond-> {:query {:find []
|
||||||
@@ -37,8 +38,7 @@
|
|||||||
|
|
||||||
true
|
true
|
||||||
(merge-query {:query {:find ['?sort-default '?e] :where ['[?e :report/created ?sort-default]]}}))]
|
(merge-query {:query {:find ['?sort-default '?e] :where ['[?e :report/created ?sort-default]]}}))]
|
||||||
(->> query
|
(->> (query2 query)
|
||||||
(dc/q)
|
|
||||||
(apply-sort-3 (update args :sort conj {:sort-key "default-2" :asc true}))
|
(apply-sort-3 (update args :sort conj {:sort-key "default-2" :asc true}))
|
||||||
(apply-pagination args))))
|
(apply-pagination args))))
|
||||||
|
|
||||||
|
|||||||
@@ -4,18 +4,18 @@
|
|||||||
:refer [add-sorter-fields-2
|
:refer [add-sorter-fields-2
|
||||||
apply-pagination
|
apply-pagination
|
||||||
apply-sort-3
|
apply-sort-3
|
||||||
pull-id
|
conn
|
||||||
merge-query
|
merge-query
|
||||||
|
pull-id
|
||||||
pull-many
|
pull-many
|
||||||
visible-clients
|
query2
|
||||||
conn]]
|
visible-clients]]
|
||||||
[iol-ion.query]
|
|
||||||
[clj-time.coerce :as c]
|
[clj-time.coerce :as c]
|
||||||
[clj-time.core :as time]
|
[clj-time.core :as time]
|
||||||
[clojure.set :as set]
|
[clojure.set :as set]
|
||||||
[datomic.client.api :as dc]
|
|
||||||
[com.brunobonacci.mulog :as mu]
|
[com.brunobonacci.mulog :as mu]
|
||||||
))
|
[datomic.api :as dc]
|
||||||
|
[iol-ion.query]))
|
||||||
|
|
||||||
(defn <-datomic [result]
|
(defn <-datomic [result]
|
||||||
(-> result
|
(-> result
|
||||||
@@ -115,8 +115,7 @@
|
|||||||
:stats (:query-stats (dc/q (assoc query :query-stats true)))
|
:stats (:query-stats (dc/q (assoc query :query-stats true)))
|
||||||
:q (str query))
|
:q (str query))
|
||||||
|
|
||||||
(cond->> query
|
(cond->> (query2 query)
|
||||||
true (dc/q)
|
|
||||||
true (apply-sort-3 (assoc args :default-asc? false))
|
true (apply-sort-3 (assoc args :default-asc? false))
|
||||||
true (apply-pagination args))))
|
true (apply-pagination args))))
|
||||||
|
|
||||||
@@ -132,13 +131,13 @@
|
|||||||
(defn summarize-orders [ids]
|
(defn summarize-orders [ids]
|
||||||
|
|
||||||
(let [[total tax] (->>
|
(let [[total tax] (->>
|
||||||
(dc/q {:query {:find ['(sum ?t) '(sum ?tax)]
|
(dc/q {:find ['(sum ?t) '(sum ?tax)]
|
||||||
:with ['?id]
|
:with ['?id]
|
||||||
:in ['$ '[?id ...]]
|
:in ['$ '[?id ...]]
|
||||||
:where ['[?id :sales-order/total ?t]
|
:where ['[?id :sales-order/total ?t]
|
||||||
'[?id :sales-order/tax ?tax]]}
|
'[?id :sales-order/tax ?tax]]}
|
||||||
:args [(dc/db conn)
|
(dc/db conn)
|
||||||
ids]})
|
ids)
|
||||||
first)]
|
first)]
|
||||||
{:total total
|
{:total total
|
||||||
:tax tax}))
|
:tax tax}))
|
||||||
|
|||||||
@@ -6,10 +6,11 @@
|
|||||||
apply-sort-3
|
apply-sort-3
|
||||||
conn
|
conn
|
||||||
merge-query
|
merge-query
|
||||||
pull-many]]
|
pull-many
|
||||||
|
query2]]
|
||||||
[auto-ap.graphql.utils :refer [limited-clients]]
|
[auto-ap.graphql.utils :refer [limited-clients]]
|
||||||
[clojure.string :as str]
|
[clojure.string :as str]
|
||||||
[datomic.client.api :as dc]))
|
[datomic.api :as dc]))
|
||||||
|
|
||||||
(defn <-datomic [result]
|
(defn <-datomic [result]
|
||||||
result)
|
result)
|
||||||
@@ -82,8 +83,7 @@
|
|||||||
:where ['[?e :transaction-rule/transaction-approval-status]]}}))]
|
:where ['[?e :transaction-rule/transaction-approval-status]]}}))]
|
||||||
|
|
||||||
|
|
||||||
(cond->> query
|
(cond->> (query2 query)
|
||||||
true (dc/q)
|
|
||||||
true (apply-sort-3 args)
|
true (apply-sort-3 args)
|
||||||
true (apply-pagination args))))
|
true (apply-pagination args))))
|
||||||
|
|
||||||
@@ -109,10 +109,10 @@
|
|||||||
|
|
||||||
(defn get-all []
|
(defn get-all []
|
||||||
(mapv first
|
(mapv first
|
||||||
(dc/q {:query {:find [(list 'pull '?e default-read )]
|
(dc/q {:find [(list 'pull '?e default-read )]
|
||||||
:in ['$]
|
:in ['$]
|
||||||
:where ['[?e :transaction-rule/transaction-approval-status]]}
|
:where ['[?e :transaction-rule/transaction-approval-status]]}
|
||||||
:args [(dc/db conn)]})))
|
(dc/db conn))))
|
||||||
|
|
||||||
(defn get-all-for-client [client-id]
|
(defn get-all-for-client [client-id]
|
||||||
(mapv first
|
(mapv first
|
||||||
|
|||||||
@@ -1,13 +1,19 @@
|
|||||||
(ns auto-ap.datomic.transactions
|
(ns auto-ap.datomic.transactions
|
||||||
(:require
|
(:require
|
||||||
[auto-ap.datomic
|
[auto-ap.datomic
|
||||||
:refer [add-sorter-fields apply-pagination apply-sort-3 conn merge-query conn pull-many]]
|
:refer [add-sorter-fields
|
||||||
|
apply-pagination
|
||||||
|
apply-sort-3
|
||||||
|
conn
|
||||||
|
merge-query
|
||||||
|
pull-many
|
||||||
|
query2]]
|
||||||
[auto-ap.datomic.accounts :as d-accounts]
|
[auto-ap.datomic.accounts :as d-accounts]
|
||||||
[auto-ap.graphql.utils :refer [limited-clients]]
|
[auto-ap.graphql.utils :refer [limited-clients]]
|
||||||
[clj-time.coerce :as coerce]
|
[clj-time.coerce :as coerce]
|
||||||
[clojure.string :as str]
|
[clojure.string :as str]
|
||||||
[clojure.tools.logging :as log]
|
[clojure.tools.logging :as log]
|
||||||
[datomic.client.api :as dc]))
|
[datomic.api :as dc]))
|
||||||
|
|
||||||
(defn potential-duplicate-ids [db args]
|
(defn potential-duplicate-ids [db args]
|
||||||
(when (and (:potential-duplicates args)
|
(when (and (:potential-duplicates args)
|
||||||
@@ -168,8 +174,7 @@
|
|||||||
'[?e :transaction/date ?sort-default]
|
'[?e :transaction/date ?sort-default]
|
||||||
'(not [?e :transaction/approval-status :transaction-approval-status/suppressed])]}}))]
|
'(not [?e :transaction/approval-status :transaction-approval-status/suppressed])]}}))]
|
||||||
(log/info "query is" query)
|
(log/info "query is" query)
|
||||||
(cond->> query
|
(cond->> (query2 query)
|
||||||
true (dc/q)
|
|
||||||
true (apply-sort-3 (assoc args :default-asc? false))
|
true (apply-sort-3 (assoc args :default-asc? false))
|
||||||
true (apply-pagination args)))))
|
true (apply-pagination args)))))
|
||||||
|
|
||||||
@@ -220,11 +225,10 @@
|
|||||||
|
|
||||||
(defn filter-ids [ids]
|
(defn filter-ids [ids]
|
||||||
(if ids
|
(if ids
|
||||||
(->> {:query {:find ['?e]
|
(->> (dc/q {:find ['?e]
|
||||||
:in ['$ '[?e ...]]
|
:in ['$ '[?e ...]]
|
||||||
:where ['[?e :transaction/date]]}
|
:where ['[?e :transaction/date]]}
|
||||||
:args [(dc/db conn) ids]}
|
(dc/db conn) ids)
|
||||||
(dc/q)
|
|
||||||
(map first)
|
(map first)
|
||||||
vec)
|
vec)
|
||||||
[]))
|
[]))
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
(ns auto-ap.datomic.users
|
(ns auto-ap.datomic.users
|
||||||
(:require
|
(:require
|
||||||
[auto-ap.datomic :refer [conn]]
|
[auto-ap.datomic :refer [conn]]
|
||||||
[datomic.client.api :as dc]))
|
[datomic.api :as dc]))
|
||||||
|
|
||||||
(defn add-arg [query name value where & rest]
|
(defn add-arg [query name value where & rest]
|
||||||
(let [query (-> query
|
(let [query (-> query
|
||||||
@@ -11,53 +11,46 @@
|
|||||||
(reduce #(update-in %1 [:query :where] conj %2) query rest)))
|
(reduce #(update-in %1 [:query :where] conj %2) query rest)))
|
||||||
|
|
||||||
(defn get-by-id [id]
|
(defn get-by-id [id]
|
||||||
(let [query (-> {:query {:find ['(pull ?e [*
|
(->> [(dc/pull (dc/db conn)
|
||||||
|
'[*
|
||||||
{:user/clients [*]}
|
{:user/clients [*]}
|
||||||
{:user/role [:db/ident]}])]
|
{:user/role [:db/ident]}]
|
||||||
:in ['$]
|
id)]
|
||||||
:where []}
|
|
||||||
:args [(dc/db conn)]}
|
|
||||||
(add-arg '?e id ['?e]))]
|
|
||||||
(->> (dc/q query)
|
|
||||||
(map first)
|
|
||||||
(map #(update % :user/role :db/ident))
|
(map #(update % :user/role :db/ident))
|
||||||
first)))
|
first))
|
||||||
|
|
||||||
(defn find-or-insert! [{:keys [:user/provider :user/provider-id] :as new-user}]
|
(defn find-or-insert! [{:keys [:user/provider :user/provider-id] :as new-user}]
|
||||||
(let [is-first-user? (not (seq (dc/q {:query [:find '?e
|
(let [is-first-user? (not (seq (dc/q [:find '?e
|
||||||
:in '$
|
:in '$
|
||||||
:where '[?e :user/provider]]
|
:where '[?e :user/provider]]
|
||||||
:args [(dc/db conn)]})))
|
(dc/db conn))))
|
||||||
user (some-> {:query [:find '(pull ?e [*
|
user (some-> (dc/q [:find '(pull ?e [*
|
||||||
{:user/clients [*]}
|
{:user/clients [*]}
|
||||||
{:user/role [:db/ident]}])
|
{:user/role [:db/ident]}])
|
||||||
:in '$ '?provider '?provider-id
|
:in '$ '?provider '?provider-id
|
||||||
:where '[?e :user/provider ?provider]
|
:where '[?e :user/provider ?provider]
|
||||||
'[?e :user/provider-id ?provider-id]]
|
'[?e :user/provider-id ?provider-id]]
|
||||||
:args [(dc/db conn) provider provider-id]}
|
(dc/db conn) provider provider-id)
|
||||||
(dc/q)
|
|
||||||
first
|
first
|
||||||
first
|
first
|
||||||
(update :user/role :db/ident))]
|
(update :user/role :db/ident))]
|
||||||
(if user
|
(if user
|
||||||
user
|
user
|
||||||
(let [new-user-trans (dc/transact conn {:tx-data [(cond-> new-user
|
(let [new-user-trans @(dc/transact conn [(cond-> new-user
|
||||||
true (assoc :db/id "user")
|
true (assoc :db/id "user")
|
||||||
is-first-user? (assoc :user/role :user-role/admin))]})]
|
is-first-user? (assoc :user/role :user-role/admin))])]
|
||||||
(get-by-id (-> new-user-trans :tempids (get "user")))))))
|
(get-by-id (-> new-user-trans :tempids (get "user")))))))
|
||||||
|
|
||||||
(defn raw-graphql [_]
|
(defn raw-graphql [_]
|
||||||
(let [query (cond-> {:query {:find ['(pull ?e [*
|
(->> (dc/q {:find ['(pull ?e [*
|
||||||
{:user/clients [*]}
|
{:user/clients [*]}
|
||||||
{:user/role [:db/ident]}])]
|
{:user/role [:db/ident]}])]
|
||||||
:in ['$]
|
:in ['$]
|
||||||
:where ['[?e :user/role]]}
|
:where ['[?e :user/role]]}
|
||||||
:args [(dc/db conn)]})]
|
(dc/db conn))
|
||||||
|
|
||||||
(->> (dc/q query)
|
|
||||||
(map first)
|
(map first)
|
||||||
(map #(update % :user/role :db/ident))
|
(map #(update % :user/role :db/ident))
|
||||||
)))
|
))
|
||||||
|
|
||||||
(defn sort-fn [args]
|
(defn sort-fn [args]
|
||||||
(cond
|
(cond
|
||||||
|
|||||||
@@ -1,10 +1,17 @@
|
|||||||
(ns auto-ap.datomic.vendors
|
(ns auto-ap.datomic.vendors
|
||||||
(:require
|
(:require
|
||||||
[auto-ap.datomic :refer [conn merge-query add-sorter-fields apply-pagination merge-query apply-sort-3 pull-many]]
|
[auto-ap.datomic
|
||||||
|
:refer [add-sorter-fields
|
||||||
|
apply-pagination
|
||||||
|
apply-sort-3
|
||||||
|
conn
|
||||||
|
merge-query
|
||||||
|
pull-many
|
||||||
|
query2]]
|
||||||
|
[auto-ap.datomic.accounts :as d-accounts]
|
||||||
[auto-ap.graphql.utils :refer [limited-clients]]
|
[auto-ap.graphql.utils :refer [limited-clients]]
|
||||||
[clojure.string :as str]
|
[clojure.string :as str]
|
||||||
[datomic.client.api :as dc]
|
[datomic.api :as dc]))
|
||||||
[auto-ap.datomic.accounts :as d-accounts]))
|
|
||||||
|
|
||||||
(defn <-datomic [a]
|
(defn <-datomic [a]
|
||||||
(cond-> a
|
(cond-> a
|
||||||
@@ -63,8 +70,7 @@
|
|||||||
:where ['[?e :vendor/name]]}}))]
|
:where ['[?e :vendor/name]]}}))]
|
||||||
|
|
||||||
|
|
||||||
(cond->> query
|
(cond->> (query2 query)
|
||||||
true (dc/q)
|
|
||||||
true (apply-sort-3 args)
|
true (apply-sort-3 args)
|
||||||
true (apply-pagination args))))
|
true (apply-pagination args))))
|
||||||
|
|
||||||
@@ -102,11 +108,10 @@
|
|||||||
)
|
)
|
||||||
|
|
||||||
(defn get-graphql-by-id [args id]
|
(defn get-graphql-by-id [args id]
|
||||||
(->> (cond-> {:query {:find [(list 'pull '?e default-read)]
|
(->> (dc/q {:find [(list 'pull '?e default-read)]
|
||||||
:in ['$ '?e]
|
:in ['$ '?e]
|
||||||
:where ['[?e :vendor/name]]}
|
:where ['[?e :vendor/name]]}
|
||||||
:args [(dc/db conn) id]})
|
(dc/db conn) id)
|
||||||
(dc/q)
|
|
||||||
(map first)
|
(map first)
|
||||||
(map #(cleanse (:id args) %))
|
(map #(cleanse (:id args) %))
|
||||||
(map <-datomic)
|
(map <-datomic)
|
||||||
|
|||||||
@@ -1,10 +1,16 @@
|
|||||||
(ns auto-ap.datomic.yodlee2
|
(ns auto-ap.datomic.yodlee2
|
||||||
(:require
|
(:require
|
||||||
[auto-ap.datomic
|
[auto-ap.datomic
|
||||||
:refer [add-sorter-fields apply-pagination apply-sort-3 merge-query conn pull-many]]
|
:refer [add-sorter-fields
|
||||||
|
apply-pagination
|
||||||
|
apply-sort-3
|
||||||
|
conn
|
||||||
|
merge-query
|
||||||
|
pull-many
|
||||||
|
query2]]
|
||||||
[auto-ap.graphql.utils :refer [limited-clients]]
|
[auto-ap.graphql.utils :refer [limited-clients]]
|
||||||
[clj-time.coerce :as c]
|
[clj-time.coerce :as c]
|
||||||
[datomic.client.api :as dc]))
|
[datomic.api :as dc]))
|
||||||
|
|
||||||
(def default-read '[*])
|
(def default-read '[*])
|
||||||
|
|
||||||
@@ -39,7 +45,7 @@
|
|||||||
(merge-query {:query {:find ['?e ]
|
(merge-query {:query {:find ['?e ]
|
||||||
:where ['[?e :yodlee-provider-account/id]]}}) )
|
:where ['[?e :yodlee-provider-account/id]]}}) )
|
||||||
|
|
||||||
(dc/q)
|
(query2)
|
||||||
(apply-sort-3 args)
|
(apply-sort-3 args)
|
||||||
(apply-pagination args)))
|
(apply-pagination args)))
|
||||||
|
|
||||||
|
|||||||
@@ -1,14 +1,13 @@
|
|||||||
(ns auto-ap.datomic.yodlee-merchants
|
(ns auto-ap.datomic.yodlee-merchants
|
||||||
(:require
|
(:require
|
||||||
[auto-ap.datomic :refer [conn]]
|
[auto-ap.datomic :refer [conn]]
|
||||||
[datomic.client.api :as dc]))
|
[datomic.api :as dc]))
|
||||||
|
|
||||||
(defn get-merchants [_]
|
(defn get-merchants [_]
|
||||||
;; TODO admin?
|
;; TODO admin?
|
||||||
(let [query {:query {:find ['(pull ?e [:yodlee-merchant/name :yodlee-merchant/yodlee-id :db/id])]
|
(->>
|
||||||
|
(dc/q {:find ['(pull ?e [:yodlee-merchant/name :yodlee-merchant/yodlee-id :db/id])]
|
||||||
:in ['$]
|
:in ['$]
|
||||||
:where [['?e :yodlee-merchant/name]]}
|
:where [['?e :yodlee-merchant/name]]}
|
||||||
:args [(dc/db conn)]}]
|
(dc/db conn))
|
||||||
(->>
|
(mapv first)))
|
||||||
(dc/q query)
|
|
||||||
(mapv first))))
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
(ns auto-ap.ezcater.core
|
(ns auto-ap.ezcater.core
|
||||||
(:require
|
(:require
|
||||||
[auto-ap.datomic :refer [conn random-tempid]]
|
[auto-ap.datomic :refer [conn random-tempid]]
|
||||||
[datomic.client.api :as dc]
|
[datomic.api :as dc]
|
||||||
[clj-http.client :as client]
|
[clj-http.client :as client]
|
||||||
[venia.core :as v]
|
[venia.core :as v]
|
||||||
[clojure.string :as str]
|
[clojure.string :as str]
|
||||||
@@ -44,21 +44,21 @@
|
|||||||
(dc/db conn))))
|
(dc/db conn))))
|
||||||
|
|
||||||
(defn mark-integration-status [integration integration-status]
|
(defn mark-integration-status [integration integration-status]
|
||||||
(dc/transact conn
|
@(dc/transact conn
|
||||||
{:tx-data [{:db/id (:db/id integration)
|
[{:db/id (:db/id integration)
|
||||||
:ezcater-integration/integration-status (assoc integration-status
|
:ezcater-integration/integration-status (assoc integration-status
|
||||||
:db/id (or (-> integration :ezcater-integration/integration-status :db/id)
|
:db/id (or (-> integration :ezcater-integration/integration-status :db/id)
|
||||||
(random-tempid)))}]}))
|
(random-tempid)))}]))
|
||||||
|
|
||||||
(defn upsert-caterers
|
(defn upsert-caterers
|
||||||
([integration]
|
([integration]
|
||||||
(dc/transact
|
@(dc/transact
|
||||||
conn
|
conn
|
||||||
{:tx-data (for [caterer (get-caterers integration)]
|
(for [caterer (get-caterers integration)]
|
||||||
{:db/id (:db/id integration)
|
{:db/id (:db/id integration)
|
||||||
:ezcater-integration/caterers [{:ezcater-caterer/name (str (:name caterer) " (" (:street (:address caterer)) ")")
|
:ezcater-integration/caterers [{:ezcater-caterer/name (str (:name caterer) " (" (:street (:address caterer)) ")")
|
||||||
:ezcater-caterer/search-terms (str (:name caterer) " " (:street (:address caterer)))
|
:ezcater-caterer/search-terms (str (:name caterer) " " (:street (:address caterer)))
|
||||||
:ezcater-caterer/uuid (:uuid caterer)}]})})))
|
:ezcater-caterer/uuid (:uuid caterer)}]}))))
|
||||||
|
|
||||||
(defn upsert-used-subscriptions
|
(defn upsert-used-subscriptions
|
||||||
([integration]
|
([integration]
|
||||||
@@ -270,12 +270,12 @@
|
|||||||
(alog/info
|
(alog/info
|
||||||
::try-import-order
|
::try-import-order
|
||||||
:json json)
|
:json json)
|
||||||
(dc/transact conn {:tx-data (filter identity
|
@(dc/transact conn (filter identity
|
||||||
[(some-> json
|
[(some-> json
|
||||||
(lookup-order)
|
(lookup-order)
|
||||||
(order->sales-order)
|
(order->sales-order)
|
||||||
(update :sales-order/date coerce/to-date)
|
(update :sales-order/date coerce/to-date)
|
||||||
(update-in [:sales-order/charges 0 :charge/date] coerce/to-date))])}))
|
(update-in [:sales-order/charges 0 :charge/date] coerce/to-date))])))
|
||||||
|
|
||||||
(defn upsert-recent []
|
(defn upsert-recent []
|
||||||
(upsert-ezcater)
|
(upsert-ezcater)
|
||||||
@@ -346,6 +346,6 @@
|
|||||||
updated-order))]
|
updated-order))]
|
||||||
(alog/info :found-orders-to-update
|
(alog/info :found-orders-to-update
|
||||||
:orders orders-to-update)
|
:orders orders-to-update)
|
||||||
(dc/transact conn {:tx-data orders-to-update})))
|
@(dc/transact conn orders-to-update)))
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
(ns auto-ap.graphql
|
(ns auto-ap.graphql
|
||||||
(:require
|
(:require
|
||||||
[auto-ap.datomic :refer [merge-query conn]]
|
[auto-ap.datomic :refer [conn merge-query query2]]
|
||||||
[auto-ap.datomic.users :as d-users]
|
[auto-ap.datomic.users :as d-users]
|
||||||
[auto-ap.graphql.accounts :as gq-accounts]
|
[auto-ap.graphql.accounts :as gq-accounts]
|
||||||
[auto-ap.graphql.checks :as gq-checks]
|
[auto-ap.graphql.checks :as gq-checks]
|
||||||
@@ -34,8 +34,7 @@
|
|||||||
[com.walmartlabs.lacinia :refer [execute]]
|
[com.walmartlabs.lacinia :refer [execute]]
|
||||||
[com.walmartlabs.lacinia.parser :as p]
|
[com.walmartlabs.lacinia.parser :as p]
|
||||||
[com.walmartlabs.lacinia.schema :as schema]
|
[com.walmartlabs.lacinia.schema :as schema]
|
||||||
[com.walmartlabs.lacinia.util :refer [attach-resolvers]]
|
[datomic.api :as dc]
|
||||||
[datomic.client.api :as dc]
|
|
||||||
[unilog.context :as lc]
|
[unilog.context :as lc]
|
||||||
[yang.time :refer [time-it]])
|
[yang.time :refer [time-it]])
|
||||||
(:import
|
(:import
|
||||||
@@ -622,7 +621,7 @@
|
|||||||
|
|
||||||
|
|
||||||
(defn get-expense-account-stats [_ {:keys [client_id] } _]
|
(defn get-expense-account-stats [_ {:keys [client_id] } _]
|
||||||
(let [result (cond-> {:query {:find ['?account '?account-name '(sum ?amount)]
|
(let [query (cond-> {:query {:find ['?account '?account-name '(sum ?amount)]
|
||||||
:in ['$]
|
:in ['$]
|
||||||
:where []}
|
:where []}
|
||||||
:args [(dc/db conn) client_id]}
|
:args [(dc/db conn) client_id]}
|
||||||
@@ -635,14 +634,13 @@
|
|||||||
'[?i :invoice/expense-accounts ?expense-account]
|
'[?i :invoice/expense-accounts ?expense-account]
|
||||||
'[?expense-account :invoice-expense-account/account ?account]
|
'[?expense-account :invoice-expense-account/account ?account]
|
||||||
'[?account :account/name ?account-name]
|
'[?account :account/name ?account-name]
|
||||||
'[?expense-account :invoice-expense-account/amount ?amount]]}})
|
'[?expense-account :invoice-expense-account/amount ?amount]]}}))
|
||||||
|
result (query2 query)]
|
||||||
true (dc/q))]
|
|
||||||
(for [[account-id account-name total] result]
|
(for [[account-id account-name total] result]
|
||||||
{:account {:id account-id :name account-name} :total total})))
|
{:account {:id account-id :name account-name} :total total})))
|
||||||
|
|
||||||
(defn get-invoice-stats [_ {:keys [client_id] } _]
|
(defn get-invoice-stats [_ {:keys [client_id] } _]
|
||||||
(let [result (cond-> {:query {:find ['?name '(sum ?outstanding-balance) '(sum ?total)]
|
(let [query (cond-> {:query {:find ['?name '(sum ?outstanding-balance) '(sum ?total)]
|
||||||
:in ['$]
|
:in ['$]
|
||||||
:where []}
|
:where []}
|
||||||
:args [(dc/db conn) client_id]}
|
:args [(dc/db conn) client_id]}
|
||||||
@@ -664,10 +662,9 @@
|
|||||||
(and [(<= ?d3 60)]
|
(and [(<= ?d3 60)]
|
||||||
[(ground :due-30) ?name])
|
[(ground :due-30) ?name])
|
||||||
(and [(> ?d3 60)]
|
(and [(> ?d3 60)]
|
||||||
[(ground :due-later) ?name]))]}})
|
[(ground :due-later) ?name]))]}}))
|
||||||
|
result (->> (query2 query)
|
||||||
true (dc/q))
|
(group-by first))]
|
||||||
result (group-by first result)]
|
|
||||||
|
|
||||||
(for [[id name] [[:due "Due"] [:due-30 "0-30 days"] [:due-60 "31-60 days"] [:due-later ">60 days"]]
|
(for [[id name] [[:due "Due"] [:due-30 "0-30 days"] [:due-60 "31-60 days"] [:due-later ">60 days"]]
|
||||||
:let [[[_ outstanding-balance total] ] (id result nil)
|
:let [[[_ outstanding-balance total] ] (id result nil)
|
||||||
@@ -699,15 +696,15 @@
|
|||||||
(- (+ total credit)
|
(- (+ total credit)
|
||||||
debit))
|
debit))
|
||||||
0.0
|
0.0
|
||||||
(dc/q {:query {:find '[?debit ?credit]
|
(dc/q {:find '[?debit ?credit]
|
||||||
:in '[$ ?client]
|
:in '[$ ?client]
|
||||||
:where ['[?client :client/bank-accounts ?ba]
|
:where ['[?client :client/bank-accounts ?ba]
|
||||||
'[?ba :bank-account/type :bank-account-type/check]
|
'[?ba :bank-account/type :bank-account-type/check]
|
||||||
'[?je :journal-entry-line/account ?ba]
|
'[?je :journal-entry-line/account ?ba]
|
||||||
'[(get-else $ ?je :journal-entry-line/debit 0.0) ?debit]
|
'[(get-else $ ?je :journal-entry-line/debit 0.0) ?debit]
|
||||||
'[(get-else $ ?je :journal-entry-line/credit 0.0) ?credit]]}
|
'[(get-else $ ?je :journal-entry-line/credit 0.0) ?credit]]}
|
||||||
:args [(dc/db conn) client_id]}))
|
(dc/db conn) client_id))
|
||||||
bills-due-soon (dc/q {:query {:find '[?due ?outstanding ?invoice-number ?vendor-id ?vendor-name]
|
bills-due-soon (dc/q {:find '[?due ?outstanding ?invoice-number ?vendor-id ?vendor-name]
|
||||||
:in '[$ ?client ?due-before]
|
:in '[$ ?client ?due-before]
|
||||||
:where ['[?i :invoice/client ?client]
|
:where ['[?i :invoice/client ?client]
|
||||||
'[?i :invoice/status :invoice-status/unpaid]
|
'[?i :invoice/status :invoice-status/unpaid]
|
||||||
@@ -717,11 +714,11 @@
|
|||||||
'[?i :invoice/invoice-number ?invoice-number]
|
'[?i :invoice/invoice-number ?invoice-number]
|
||||||
'[?i :invoice/vendor ?vendor-id]
|
'[?i :invoice/vendor ?vendor-id]
|
||||||
'[?vendor-id :vendor/name ?vendor-name]]}
|
'[?vendor-id :vendor/name ?vendor-name]]}
|
||||||
:args [(dc/db conn) client_id (coerce/to-date (t/plus (time/local-now) (t/days 180)))]})
|
(dc/db conn) client_id (coerce/to-date (t/plus (time/local-now) (t/days 180))))
|
||||||
outstanding-checks (reduce
|
outstanding-checks (reduce
|
||||||
+
|
+
|
||||||
0.0
|
0.0
|
||||||
(map first (dc/q {:query {:find '[?amount]
|
(map first (dc/q {:find '[?amount]
|
||||||
:in '[$ ?client ?due-before]
|
:in '[$ ?client ?due-before]
|
||||||
:where ['[?p :payment/client ?client]
|
:where ['[?p :payment/client ?client]
|
||||||
'[?p :payment/status :payment-status/pending]
|
'[?p :payment/status :payment-status/pending]
|
||||||
@@ -729,14 +726,14 @@
|
|||||||
'(or
|
'(or
|
||||||
[?p :payment/type :payment-type/debit]
|
[?p :payment/type :payment-type/debit]
|
||||||
[?p :payment/type :payment-type/check])]}
|
[?p :payment/type :payment-type/check])]}
|
||||||
:args [(dc/db conn) client_id (coerce/to-date (t/plus (time/local-now) (t/days 180)))]})))
|
(dc/db conn) client_id (coerce/to-date (t/plus (time/local-now) (t/days 180))))))
|
||||||
recent-fulfillments (dc/q {:query {:find '[?f ?d]
|
recent-fulfillments (dc/q {:find '[?f ?d]
|
||||||
:in '[$ ?client ?min-date]
|
:in '[$ ?client ?min-date]
|
||||||
:where ['[?t :transaction/forecast-match ?f]
|
:where ['[?t :transaction/forecast-match ?f]
|
||||||
'[?t :transaction/client ?client]
|
'[?t :transaction/client ?client]
|
||||||
'[?t :transaction/date ?d]
|
'[?t :transaction/date ?d]
|
||||||
'[(>= ?d ?min-date)]]}
|
'[(>= ?d ?min-date)]]}
|
||||||
:args [(dc/db conn) client_id (coerce/to-date (t/plus (time/local-now) (t/months -2)))]})
|
(dc/db conn) client_id (coerce/to-date (t/plus (time/local-now) (t/months -2))))
|
||||||
forecasted-transactions (for [{:forecasted-transaction/keys [amount identifier day-of-month]
|
forecasted-transactions (for [{:forecasted-transaction/keys [amount identifier day-of-month]
|
||||||
:db/keys [id]} forecasted-transactions
|
:db/keys [id]} forecasted-transactions
|
||||||
month (range -1 7)
|
month (range -1 7)
|
||||||
|
|||||||
@@ -13,8 +13,8 @@
|
|||||||
result->page]]
|
result->page]]
|
||||||
[auto-ap.search :as search]
|
[auto-ap.search :as search]
|
||||||
[auto-ap.utils :refer [heartbeat]]
|
[auto-ap.utils :refer [heartbeat]]
|
||||||
[datomic.client.api :as dc]
|
[datomic.api :as dc]
|
||||||
[iol-ion.tx :refer [random-tempid upsert-entity]]
|
[iol-ion.tx :refer [random-tempid]]
|
||||||
[mount.core :as mount]
|
[mount.core :as mount]
|
||||||
[yang.scheduler :as scheduler]))
|
[yang.scheduler :as scheduler]))
|
||||||
|
|
||||||
@@ -38,16 +38,16 @@
|
|||||||
(defn upsert-account [context args _]
|
(defn upsert-account [context args _]
|
||||||
(let [{{:keys [id client-overrides numeric-code location applicability account-set name invoice-allowance vendor-allowance type]} :account} (<-graphql args)]
|
(let [{{:keys [id client-overrides numeric-code location applicability account-set name invoice-allowance vendor-allowance type]} :account} (<-graphql args)]
|
||||||
(when-not id
|
(when-not id
|
||||||
(when (seq (dc/q {:query {:find ['?e]
|
(when (seq (dc/q {:find ['?e]
|
||||||
:in '[$ ?account-set ?numeric-code]
|
:in '[$ ?account-set ?numeric-code]
|
||||||
:where ['[?e :account/account-set ?account-set]
|
:where ['[?e :account/account-set ?account-set]
|
||||||
'[?e :account/numeric-code ?numeric-code]]}
|
'[?e :account/numeric-code ?numeric-code]]}
|
||||||
:args [(dc/db conn) account-set numeric-code]}))
|
(dc/db conn) account-set numeric-code))
|
||||||
|
|
||||||
(throw (ex-info (str "Account set " account-set " already has an account for code " numeric-code)
|
(throw (ex-info (str "Account set " account-set " already has an account for code " numeric-code)
|
||||||
{} ))))
|
{} ))))
|
||||||
(let [result (audit-transact [`(upsert-entity
|
(let [result (audit-transact [[:upsert-entity
|
||||||
~(cond-> {:db/id (or id "new-account")
|
(cond-> {:db/id (or id "new-account")
|
||||||
:account/name name
|
:account/name name
|
||||||
:account/search-terms name
|
:account/search-terms name
|
||||||
:account/type (keyword "account-type" (clojure.core/name type))
|
:account/type (keyword "account-type" (clojure.core/name type))
|
||||||
@@ -67,7 +67,7 @@
|
|||||||
:account-client-override/name (:name client-override)
|
:account-client-override/name (:name client-override)
|
||||||
:account-client-override/search-terms (:name client-override)})
|
:account-client-override/search-terms (:name client-override)})
|
||||||
client-overrides)}
|
client-overrides)}
|
||||||
id (dissoc :account/numeric-code :account/code)))]
|
id (dissoc :account/numeric-code :account/code))]]
|
||||||
(:id context))]
|
(:id context))]
|
||||||
(->graphql
|
(->graphql
|
||||||
(d-accounts/get-by-id (or id (get-in result [:tempids "new-account"])))))))
|
(d-accounts/get-by-id (or id (get-in result [:tempids "new-account"])))))))
|
||||||
@@ -149,12 +149,12 @@
|
|||||||
|
|
||||||
(defn rebuild-search-index []
|
(defn rebuild-search-index []
|
||||||
(search/full-index-query
|
(search/full-index-query
|
||||||
(for [result (map first (dc/qseq '[:find (pull ?aco [:account-client-override/search-terms :account-client-override/client :db/id {:account/_client-overrides [:account/numeric-code :account/location :db/id]}])
|
(for [result (map first (dc/qseq {:query '[:find (pull ?aco [:account-client-override/search-terms :account-client-override/client :db/id {:account/_client-overrides [:account/numeric-code :account/location :db/id]}])
|
||||||
:in $
|
:in $
|
||||||
:where [?aco :account-client-override/client ]
|
:where [?aco :account-client-override/client ]
|
||||||
[?aco :account-client-override/search-terms ]
|
[?aco :account-client-override/search-terms ]
|
||||||
[_ :account/client-overrides ?aco]]
|
[_ :account/client-overrides ?aco]]
|
||||||
(dc/db conn)))
|
:args [(dc/db conn)]}))
|
||||||
:when (:account/numeric-code (:account/_client-overrides result))]
|
:when (:account/numeric-code (:account/_client-overrides result))]
|
||||||
{:id (:db/id (:account/_client-overrides result))
|
{:id (:db/id (:account/_client-overrides result))
|
||||||
:account-client-override-id (:db/id result)
|
:account-client-override-id (:db/id result)
|
||||||
@@ -165,14 +165,14 @@
|
|||||||
"account-client-override")
|
"account-client-override")
|
||||||
|
|
||||||
(search/full-index-query
|
(search/full-index-query
|
||||||
(for [result (map first (dc/qseq '[:find (pull ?a [:account/numeric-code
|
(for [result (map first (dc/qseq {:query '[:find (pull ?a [:account/numeric-code
|
||||||
:account/search-terms
|
:account/search-terms
|
||||||
{:account/applicability [:db/ident]}
|
{:account/applicability [:db/ident]}
|
||||||
:db/id
|
:db/id
|
||||||
:account/location])
|
:account/location])
|
||||||
:in $
|
:in $
|
||||||
:where [?a :account/search-terms ]]
|
:where [?a :account/search-terms ]]
|
||||||
(dc/db conn)))
|
:args [(dc/db conn)]}))
|
||||||
:when (:account/search-terms result)
|
:when (:account/search-terms result)
|
||||||
]
|
]
|
||||||
{:id (:db/id result)
|
{:id (:db/id result)
|
||||||
@@ -183,11 +183,11 @@
|
|||||||
"account"))
|
"account"))
|
||||||
|
|
||||||
#_(dc/transact conn
|
#_(dc/transact conn
|
||||||
{:tx-data [{:db/ident :account-client-override/k2
|
[{:db/ident :account-client-override/k2
|
||||||
:db/valueType :db.type/tuple
|
:db/valueType :db.type/tuple
|
||||||
:db/tupleAttrs [:account/_client-overrides :account-client-override/client ]
|
:db/tupleAttrs [:account/_client-overrides :account-client-override/client ]
|
||||||
:db/cardinality :db.cardinality/one
|
:db/cardinality :db.cardinality/one
|
||||||
:db/unique :db.unique/identity}]})
|
:db/unique :db.unique/identity}])
|
||||||
|
|
||||||
#_(dc/q '[:find ?o
|
#_(dc/q '[:find ?o
|
||||||
:where [_ :account-client-override/k ?o]]
|
:where [_ :account-client-override/k ?o]]
|
||||||
|
|||||||
@@ -3,7 +3,6 @@
|
|||||||
[amazonica.aws.s3 :as s3]
|
[amazonica.aws.s3 :as s3]
|
||||||
[auto-ap.datomic :refer [conn remove-nils pull-many audit-transact]]
|
[auto-ap.datomic :refer [conn remove-nils pull-many audit-transact]]
|
||||||
[auto-ap.datomic.accounts :as a]
|
[auto-ap.datomic.accounts :as a]
|
||||||
[iol-ion.tx :refer [upsert-invoice pay plus]]
|
|
||||||
[auto-ap.datomic.bank-accounts :as d-bank-accounts]
|
[auto-ap.datomic.bank-accounts :as d-bank-accounts]
|
||||||
[auto-ap.datomic.checks :as d-checks]
|
[auto-ap.datomic.checks :as d-checks]
|
||||||
[auto-ap.datomic.clients :as d-clients]
|
[auto-ap.datomic.clients :as d-clients]
|
||||||
@@ -35,7 +34,7 @@
|
|||||||
[com.walmartlabs.lacinia.util :refer [attach-resolvers]]
|
[com.walmartlabs.lacinia.util :refer [attach-resolvers]]
|
||||||
[config.core :refer [env]]
|
[config.core :refer [env]]
|
||||||
[clj-time.coerce :as coerce]
|
[clj-time.coerce :as coerce]
|
||||||
[datomic.client.api :as dc]
|
[datomic.api :as dc]
|
||||||
[digest])
|
[digest])
|
||||||
(:import
|
(:import
|
||||||
(java.io ByteArrayOutputStream)
|
(java.io ByteArrayOutputStream)
|
||||||
@@ -230,7 +229,7 @@
|
|||||||
[{:invoice-payment/payment (-> invoice :invoice/vendor :db/id str)
|
[{:invoice-payment/payment (-> invoice :invoice/vendor :db/id str)
|
||||||
:invoice-payment/amount invoice-amount
|
:invoice-payment/amount invoice-amount
|
||||||
:invoice-payment/invoice (:db/id invoice)}
|
:invoice-payment/invoice (:db/id invoice)}
|
||||||
`(pay ~(:db/id invoice) ~invoice-amount)])
|
[:pay (:db/id invoice) invoice-amount]])
|
||||||
(reduce into [])))
|
(reduce into [])))
|
||||||
|
|
||||||
(defn base-payment [invoices vendor client bank-account _ _ invoice-amounts]
|
(defn base-payment [invoices vendor client bank-account _ _ invoice-amounts]
|
||||||
@@ -408,7 +407,7 @@
|
|||||||
(reduce into [])
|
(reduce into [])
|
||||||
doall))
|
doall))
|
||||||
checks (if (= type :payment-type/check)
|
checks (if (= type :payment-type/check)
|
||||||
(conj checks `(plus ~(:db/id bank-account) ~:bank-account/check-number ~(count invoices-grouped-by-vendor)))
|
(conj checks [:plus (:db/id bank-account) :bank-account/check-number (count invoices-grouped-by-vendor)])
|
||||||
checks)]
|
checks)]
|
||||||
(when (= type :payment-type/check)
|
(when (= type :payment-type/check)
|
||||||
(mu/trace ::making-pdfs [:checks checks]
|
(mu/trace ::making-pdfs [:checks checks]
|
||||||
@@ -501,11 +500,11 @@
|
|||||||
new-balance (+ (:invoice/outstanding-balance invoice)
|
new-balance (+ (:invoice/outstanding-balance invoice)
|
||||||
(:invoice-payment/amount x))]
|
(:invoice-payment/amount x))]
|
||||||
[[:db/retractEntity (:db/id x)]
|
[[:db/retractEntity (:db/id x)]
|
||||||
`(upsert-invoice ~{:db/id (:db/id invoice)
|
[:upsert-invoice {:db/id (:db/id invoice)
|
||||||
:invoice/outstanding-balance new-balance
|
:invoice/outstanding-balance new-balance
|
||||||
:invoice/status (if (dollars-0? new-balance)
|
:invoice/status (if (dollars-0? new-balance)
|
||||||
(:invoice/status invoice)
|
(:invoice/status invoice)
|
||||||
:invoice-status/unpaid)})]))
|
:invoice-status/unpaid)}]]))
|
||||||
(:payment/invoices check))
|
(:payment/invoices check))
|
||||||
updated-payment {:db/id id
|
updated-payment {:db/id id
|
||||||
:payment/amount 0.0
|
:payment/amount 0.0
|
||||||
@@ -543,11 +542,11 @@
|
|||||||
(let [new-balance (+ (:invoice/outstanding-balance invoice)
|
(let [new-balance (+ (:invoice/outstanding-balance invoice)
|
||||||
amount)]
|
amount)]
|
||||||
[[:db.fn/retractEntity id]
|
[[:db.fn/retractEntity id]
|
||||||
`(upsert-invoice ~{:db/id (:db/id invoice)
|
[:upsert-invoice {:db/id (:db/id invoice)
|
||||||
:invoice/outstanding-balance new-balance
|
:invoice/outstanding-balance new-balance
|
||||||
:invoice/status (if (dollars-0? new-balance)
|
:invoice/status (if (dollars-0? new-balance)
|
||||||
(:invoice/status invoice)
|
(:invoice/status invoice)
|
||||||
:invoice-status/unpaid)})]))))))))
|
:invoice-status/unpaid)}]]))))))))
|
||||||
id))
|
id))
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -20,8 +20,8 @@
|
|||||||
[clojure.string :as str]
|
[clojure.string :as str]
|
||||||
[clojure.tools.logging :as log]
|
[clojure.tools.logging :as log]
|
||||||
[com.brunobonacci.mulog :as mu]
|
[com.brunobonacci.mulog :as mu]
|
||||||
[datomic.client.api :as dc]
|
[datomic.api :as dc]
|
||||||
[iol-ion.tx :refer [random-tempid upsert-entity]]
|
[iol-ion.tx :refer [random-tempid]]
|
||||||
[mount.core :as mount]
|
[mount.core :as mount]
|
||||||
[unilog.context :as lc]
|
[unilog.context :as lc]
|
||||||
[yang.scheduler :as scheduler])
|
[yang.scheduler :as scheduler])
|
||||||
@@ -30,10 +30,10 @@
|
|||||||
(org.apache.commons.codec.binary Base64)))
|
(org.apache.commons.codec.binary Base64)))
|
||||||
|
|
||||||
(defn assert-client-code-is-unique [code]
|
(defn assert-client-code-is-unique [code]
|
||||||
(when (seq (dc/q {:query {:find '[?id]
|
(when (seq (dc/q {:find '[?id]
|
||||||
:in ['$ '?code]
|
:in ['$ '?code]
|
||||||
:where ['[?id :client/code ?code]]}
|
:where ['[?id :client/code ?code]]}
|
||||||
:args [(dc/db conn) code]}))
|
(dc/db conn) code))
|
||||||
(throw (ex-info "Client is not unique" {:validation-error (str "Client code '" code "' is not unique.")}))))
|
(throw (ex-info "Client is not unique" {:validation-error (str "Client code '" code "' is not unique.")}))))
|
||||||
|
|
||||||
(defn upload-signature-data [signature-data]
|
(defn upload-signature-data [signature-data]
|
||||||
@@ -52,8 +52,8 @@
|
|||||||
(str "https://integreat-signature-images.s3.amazonaws.com/" signature-id ".jpg")))))
|
(str "https://integreat-signature-images.s3.amazonaws.com/" signature-id ".jpg")))))
|
||||||
|
|
||||||
(defn assert-no-shared-transaction-sources [client-code txes]
|
(defn assert-no-shared-transaction-sources [client-code txes]
|
||||||
(let [new-db (:db-after (dc/with (dc/with-db conn)
|
(let [new-db (:db-after (dc/with (dc/db conn)
|
||||||
{:tx-data txes}))]
|
txes))]
|
||||||
(when (seq (->> (dc/q '[:find ?src (count ?ba)
|
(when (seq (->> (dc/q '[:find ?src (count ?ba)
|
||||||
:in $ ?c
|
:in $ ?c
|
||||||
:where [?c :client/bank-accounts ?ba]
|
:where [?c :client/bank-accounts ?ba]
|
||||||
@@ -150,10 +150,10 @@
|
|||||||
|
|
||||||
}
|
}
|
||||||
_ (mu/log ::upserting :up updated-entity)
|
_ (mu/log ::upserting :up updated-entity)
|
||||||
_ (assert-no-shared-transaction-sources client-code [`(upsert-entity ~updated-entity)])
|
_ (assert-no-shared-transaction-sources client-code [[:upsert-entity updated-entity]])
|
||||||
_ (log/info "upserting client" updated-entity)
|
_ (log/info "upserting client" updated-entity)
|
||||||
|
|
||||||
result (audit-transact [`(upsert-entity ~updated-entity)] (:id context))]
|
result (audit-transact [[:upsert-entity updated-entity]] (:id context))]
|
||||||
(when (:square_auth_token edit_client)
|
(when (:square_auth_token edit_client)
|
||||||
(square/upsert-locations (-> result :tempids (get id) (or id) d-clients/get-by-id)))
|
(square/upsert-locations (-> result :tempids (get id) (or id) d-clients/get-by-id)))
|
||||||
(-> (-> result :tempids (get id) (or id) d-clients/get-by-id)
|
(-> (-> result :tempids (get id) (or id) d-clients/get-by-id)
|
||||||
@@ -178,8 +178,7 @@
|
|||||||
clients (dc/q '[:find (pull ?c [:db/id :client/code {:client/bank-accounts [:db/id :bank-account/code]}])
|
clients (dc/q '[:find (pull ?c [:db/id :client/code {:client/bank-accounts [:db/id :bank-account/code]}])
|
||||||
:where [?c :client/code]]
|
:where [?c :client/code]]
|
||||||
db )]
|
db )]
|
||||||
(dc/transact conn
|
@(dc/transact conn
|
||||||
{:tx-data
|
|
||||||
(for [[{client :db/id code :client/code bank-accounts :client/bank-accounts}] clients
|
(for [[{client :db/id code :client/code bank-accounts :client/bank-accounts}] clients
|
||||||
{bank-account :db/id bac :bank-account/code} bank-accounts]
|
{bank-account :db/id bac :bank-account/code} bank-accounts]
|
||||||
{:db/id bank-account
|
{:db/id bank-account
|
||||||
@@ -197,7 +196,7 @@
|
|||||||
(= b bank-account))))
|
(= b bank-account))))
|
||||||
(map :journal-entry-line/running-balance)
|
(map :journal-entry-line/running-balance)
|
||||||
(first))
|
(first))
|
||||||
0.0)})}))))
|
0.0)})))))
|
||||||
|
|
||||||
(defn get-client [context _ _]
|
(defn get-client [context _ _]
|
||||||
(->graphql
|
(->graphql
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
:refer [assert-admin attach-tracing-resolvers cleanse-query]]
|
:refer [assert-admin attach-tracing-resolvers cleanse-query]]
|
||||||
[auto-ap.search :as search]
|
[auto-ap.search :as search]
|
||||||
[auto-ap.utils :refer [heartbeat]]
|
[auto-ap.utils :refer [heartbeat]]
|
||||||
[datomic.client.api :as dc]
|
[datomic.api :as dc]
|
||||||
[mount.core :as mount]
|
[mount.core :as mount]
|
||||||
[yang.scheduler :as scheduler]))
|
[yang.scheduler :as scheduler]))
|
||||||
|
|
||||||
@@ -19,10 +19,10 @@
|
|||||||
|
|
||||||
(defn rebuild-search-index []
|
(defn rebuild-search-index []
|
||||||
(search/full-index-query
|
(search/full-index-query
|
||||||
(for [result (map first (dc/qseq '[:find (pull ?a [:ezcater-caterer/search-terms :db/id :ezcater-caterer/name])
|
(for [result (map first (dc/qseq {:query '[:find (pull ?a [:ezcater-caterer/search-terms :db/id :ezcater-caterer/name])
|
||||||
:in $
|
:in $
|
||||||
:where [?a :ezcater-caterer/search-terms ]]
|
:where [?a :ezcater-caterer/search-terms ]]
|
||||||
(dc/db conn)))]
|
:args [(dc/db conn)]}))]
|
||||||
{:id (:db/id result)
|
{:id (:db/id result)
|
||||||
:text (:ezcater-caterer/search-terms result)})
|
:text (:ezcater-caterer/search-terms result)})
|
||||||
"ezcater-caterer"))
|
"ezcater-caterer"))
|
||||||
|
|||||||
@@ -1,12 +1,21 @@
|
|||||||
(ns auto-ap.graphql.import-batch
|
(ns auto-ap.graphql.import-batch
|
||||||
(:require
|
(:require
|
||||||
[auto-ap.datomic :refer [add-sorter-fields apply-pagination apply-sort-3 conn merge-query pull-many-by-id]]
|
[auto-ap.datomic
|
||||||
|
:refer [add-sorter-fields
|
||||||
|
apply-pagination
|
||||||
|
apply-sort-3
|
||||||
|
conn
|
||||||
|
merge-query
|
||||||
|
pull-many-by-id
|
||||||
|
query2]]
|
||||||
[auto-ap.graphql.utils
|
[auto-ap.graphql.utils
|
||||||
:refer
|
:refer [<-graphql
|
||||||
[<-graphql assert-admin ident->enum-f result->page attach-tracing-resolvers]]
|
assert-admin
|
||||||
|
attach-tracing-resolvers
|
||||||
|
ident->enum-f
|
||||||
|
result->page]]
|
||||||
[clj-time.coerce :as coerce]
|
[clj-time.coerce :as coerce]
|
||||||
[com.walmartlabs.lacinia.util :refer [attach-resolvers]]
|
[datomic.api :as dc]))
|
||||||
[datomic.client.api :as dc]))
|
|
||||||
|
|
||||||
(def default-read '[:db/id
|
(def default-read '[:db/id
|
||||||
:import-batch/external-id
|
:import-batch/external-id
|
||||||
@@ -32,8 +41,7 @@
|
|||||||
:where ['[?e :import-batch/date]]}}))]
|
:where ['[?e :import-batch/date]]}}))]
|
||||||
|
|
||||||
|
|
||||||
(cond->> query
|
(cond->> (query2 query)
|
||||||
true (dc/q)
|
|
||||||
true (apply-sort-3 args)
|
true (apply-sort-3 args)
|
||||||
true (apply-pagination args))))
|
true (apply-pagination args))))
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
(:require
|
(:require
|
||||||
[auto-ap.datomic :refer [conn]]
|
[auto-ap.datomic :refer [conn]]
|
||||||
[auto-ap.graphql.utils :refer [->graphql assert-admin]]
|
[auto-ap.graphql.utils :refer [->graphql assert-admin]]
|
||||||
[datomic.client.api :as dc]))
|
[datomic.api :as dc]))
|
||||||
|
|
||||||
(defn get-intuit-bank-accounts [context _ _]
|
(defn get-intuit-bank-accounts [context _ _]
|
||||||
(assert-admin (:id context))
|
(assert-admin (:id context))
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
(:require
|
(:require
|
||||||
[auto-ap.datomic
|
[auto-ap.datomic
|
||||||
:refer [conn pull-attr pull-many pull-ref random-tempid audit-transact audit-transact-batch]]
|
:refer [conn pull-attr pull-many pull-ref random-tempid audit-transact audit-transact-batch]]
|
||||||
[iol-ion.tx :refer [upsert-entity upsert-invoice]]
|
|
||||||
[auto-ap.datomic.clients :as d-clients]
|
[auto-ap.datomic.clients :as d-clients]
|
||||||
[auto-ap.datomic.invoices :as d-invoices]
|
[auto-ap.datomic.invoices :as d-invoices]
|
||||||
[auto-ap.datomic.vendors :as d-vendors]
|
[auto-ap.datomic.vendors :as d-vendors]
|
||||||
@@ -23,7 +22,7 @@
|
|||||||
[clj-time.core :as time]
|
[clj-time.core :as time]
|
||||||
[clojure.tools.logging :as log]
|
[clojure.tools.logging :as log]
|
||||||
[com.brunobonacci.mulog :as mu]
|
[com.brunobonacci.mulog :as mu]
|
||||||
[datomic.client.api :as dc]))
|
[datomic.api :as dc]))
|
||||||
|
|
||||||
(defn ->graphql [invoice user ]
|
(defn ->graphql [invoice user ]
|
||||||
(if (= "admin" (:user/role user))
|
(if (= "admin" (:user/role user))
|
||||||
@@ -74,7 +73,7 @@
|
|||||||
i)]]
|
i)]]
|
||||||
(assert-can-see-client (:id context) (-> invoice :invoice/client :db/id))
|
(assert-can-see-client (:id context) (-> invoice :invoice/client :db/id))
|
||||||
(assert-not-locked (-> invoice :invoice/client :db/id) (-> invoice :invoice/date)))
|
(assert-not-locked (-> invoice :invoice/client :db/id) (-> invoice :invoice/date)))
|
||||||
(let [transactions (map (fn [i] `(upsert-invoice ~{:db/id i :invoice/import-status :import-status/imported})) invoices)]
|
(let [transactions (map (fn [i] [:upsert-invoice {:db/id i :invoice/import-status :import-status/imported}]) invoices)]
|
||||||
(audit-transact transactions (:id context))
|
(audit-transact transactions (:id context))
|
||||||
invoices))
|
invoices))
|
||||||
|
|
||||||
@@ -109,7 +108,7 @@
|
|||||||
_ (when-not (:db/id account)
|
_ (when-not (:db/id account)
|
||||||
(throw (ex-info (str "Vendor '" (:vendor/name vendor) "' does not have a default expense acount.") {:vendor-id vendor_id})))]
|
(throw (ex-info (str "Vendor '" (:vendor/name vendor) "' does not have a default expense acount.") {:vendor-id vendor_id})))]
|
||||||
|
|
||||||
`(upsert-invoice ~{:db/id "invoice"
|
[:upsert-invoice {:db/id "invoice"
|
||||||
:invoice/invoice-number invoice_number
|
:invoice/invoice-number invoice_number
|
||||||
:invoice/client client_id
|
:invoice/client client_id
|
||||||
:invoice/vendor vendor_id
|
:invoice/vendor vendor_id
|
||||||
@@ -121,7 +120,7 @@
|
|||||||
:invoice/expense-accounts (map expense-account->entity
|
:invoice/expense-accounts (map expense-account->entity
|
||||||
expense_accounts)
|
expense_accounts)
|
||||||
:invoice/due (coerce/to-date due)
|
:invoice/due (coerce/to-date due)
|
||||||
:invoice/scheduled-payment (coerce/to-date scheduled_payment)})))
|
:invoice/scheduled-payment (coerce/to-date scheduled_payment)}]))
|
||||||
|
|
||||||
(defn assert-valid-expense-accounts [expense_accounts vendor_id]
|
(defn assert-valid-expense-accounts [expense_accounts vendor_id]
|
||||||
(doseq [expense-account expense_accounts
|
(doseq [expense-account expense_accounts
|
||||||
@@ -230,7 +229,7 @@
|
|||||||
expense_accounts)
|
expense_accounts)
|
||||||
:invoice/due (coerce/to-date due)
|
:invoice/due (coerce/to-date due)
|
||||||
:invoice/scheduled-payment (coerce/to-date scheduled_payment)}]
|
:invoice/scheduled-payment (coerce/to-date scheduled_payment)}]
|
||||||
(audit-transact [`(upsert-invoice ~updated-invoice)]
|
(audit-transact [[:upsert-invoice updated-invoice]]
|
||||||
(:id context))
|
(:id context))
|
||||||
(-> (d-invoices/get-by-id id)
|
(-> (d-invoices/get-by-id id)
|
||||||
(->graphql (:id context)))))
|
(->graphql (:id context)))))
|
||||||
@@ -239,13 +238,13 @@
|
|||||||
(let [invoice (d-invoices/get-by-id id)]
|
(let [invoice (d-invoices/get-by-id id)]
|
||||||
(assert-can-see-client (:id context) (:db/id (:invoice/client invoice)))
|
(assert-can-see-client (:id context) (:db/id (:invoice/client invoice)))
|
||||||
(assert-not-locked (:db/id (:invoice/client invoice)) (:invoice/date invoice))
|
(assert-not-locked (:db/id (:invoice/client invoice)) (:invoice/date invoice))
|
||||||
(audit-transact [`(upsert-invoice ~{:db/id id
|
(audit-transact [[:upsert-invoice {:db/id id
|
||||||
:invoice/total 0.0
|
:invoice/total 0.0
|
||||||
:invoice/outstanding-balance 0.0
|
:invoice/outstanding-balance 0.0
|
||||||
:invoice/status :invoice-status/voided
|
:invoice/status :invoice-status/voided
|
||||||
:invoice/expense-accounts (map (fn [ea] {:db/id (:db/id ea)
|
:invoice/expense-accounts (map (fn [ea] {:db/id (:db/id ea)
|
||||||
:invoice-expense-account/amount 0.0})
|
:invoice-expense-account/amount 0.0})
|
||||||
(:invoice/expense-accounts invoice))})]
|
(:invoice/expense-accounts invoice))}]]
|
||||||
(:id context))
|
(:id context))
|
||||||
|
|
||||||
(-> (d-invoices/get-by-id id) (->graphql (:id context)))))
|
(-> (d-invoices/get-by-id id) (->graphql (:id context)))))
|
||||||
@@ -308,7 +307,7 @@
|
|||||||
(dc/db conn))
|
(dc/db conn))
|
||||||
(map
|
(map
|
||||||
(fn [[i]]
|
(fn [[i]]
|
||||||
`(upsert-invoice ~{:db/id (:db/id i)
|
[:upsert-invoice {:db/id (:db/id i)
|
||||||
:invoice/total 0.0
|
:invoice/total 0.0
|
||||||
:invoice/outstanding-balance 0.0
|
:invoice/outstanding-balance 0.0
|
||||||
:invoice/status :invoice-status/voided
|
:invoice/status :invoice-status/voided
|
||||||
@@ -316,7 +315,7 @@
|
|||||||
(fn [iea]
|
(fn [iea]
|
||||||
{:db/id (:db/id iea)
|
{:db/id (:db/id iea)
|
||||||
:invoice-expense-account/amount 0.0})
|
:invoice-expense-account/amount 0.0})
|
||||||
(:invoice/expense-accounts i))}))))
|
(:invoice/expense-accounts i))}])))
|
||||||
(:id context))
|
(:id context))
|
||||||
{:message (str "Succesfully voided " (count all-ids))}))
|
{:message (str "Succesfully voided " (count all-ids))}))
|
||||||
|
|
||||||
@@ -325,17 +324,17 @@
|
|||||||
_ (assert-can-see-client (:id context) (:db/id (:invoice/client invoice)))
|
_ (assert-can-see-client (:id context) (:db/id (:invoice/client invoice)))
|
||||||
_ (assert-not-locked (:db/id (:invoice/client invoice)) (:invoice/date invoice))
|
_ (assert-not-locked (:db/id (:invoice/client invoice)) (:invoice/date invoice))
|
||||||
history (dc/history (dc/db conn))
|
history (dc/history (dc/db conn))
|
||||||
txs (dc/q {:query {:find ['?tx '?e '?original-status '?original-outstanding '?total '?ea '?ea-amount]
|
txs (dc/q {:find ['?tx '?e '?original-status '?original-outstanding '?total '?ea '?ea-amount]
|
||||||
:where ['[?e :invoice/status :invoice-status/voided ?tx true]
|
:where ['[?e :invoice/status :invoice-status/voided ?tx true]
|
||||||
'[?e :invoice/status ?original-status ?tx false]
|
'[?e :invoice/status ?original-status ?tx false]
|
||||||
'[?e :invoice/outstanding-balance ?original-outstanding ?tx false]
|
'[?e :invoice/outstanding-balance ?original-outstanding ?tx false]
|
||||||
'[?e :invoice/total ?total ?tx false]
|
'[?e :invoice/total ?total ?tx false]
|
||||||
'[?ea :invoice-expense-account/amount ?ea-amount ?tx false]]
|
'[?ea :invoice-expense-account/amount ?ea-amount ?tx false]]
|
||||||
:in ['$ '?e]}
|
:in ['$ '?e]}
|
||||||
:args [history id]})
|
history id)
|
||||||
[last-transaction] (->> txs (sort-by first) (last))]
|
[last-transaction] (->> txs (sort-by first) (last))]
|
||||||
(audit-transact [`(upsert-invoice
|
(audit-transact [[:upsert-invoice
|
||||||
~(->> txs
|
(->> txs
|
||||||
(filter (fn [[tx]] (= tx last-transaction)))
|
(filter (fn [[tx]] (= tx last-transaction)))
|
||||||
(reduce (fn [new-transaction [_ entity original-status original-outstanding total expense-account expense-account-amount]]
|
(reduce (fn [new-transaction [_ entity original-status original-outstanding total expense-account expense-account-amount]]
|
||||||
(-> new-transaction
|
(-> new-transaction
|
||||||
@@ -344,7 +343,7 @@
|
|||||||
:invoice/status original-status
|
:invoice/status original-status
|
||||||
:invoice/outstanding-balance original-outstanding)
|
:invoice/outstanding-balance original-outstanding)
|
||||||
(update :invoice/expense-accounts conj {:db/id expense-account :invoice-expense-account/amount expense-account-amount})))
|
(update :invoice/expense-accounts conj {:db/id expense-account :invoice-expense-account/amount expense-account-amount})))
|
||||||
{})))]
|
{}))]]
|
||||||
(:id context))
|
(:id context))
|
||||||
|
|
||||||
(-> (d-invoices/get-by-id id)
|
(-> (d-invoices/get-by-id id)
|
||||||
@@ -360,11 +359,11 @@
|
|||||||
(assert-can-see-client (:id context) (:db/id (:invoice/client invoice)))
|
(assert-can-see-client (:id context) (:db/id (:invoice/client invoice)))
|
||||||
(assert-not-locked (:db/id (:invoice/client invoice)) (:invoice/date invoice))
|
(assert-not-locked (:db/id (:invoice/client invoice)) (:invoice/date invoice))
|
||||||
(assert (not (seq (:invoice-payment/_invoice invoice))))
|
(assert (not (seq (:invoice-payment/_invoice invoice))))
|
||||||
(audit-transact [`(upsert-invoice
|
(audit-transact [[:upsert-invoice
|
||||||
~{:db/id id
|
{:db/id id
|
||||||
:invoice/status :invoice-status/unpaid
|
:invoice/status :invoice-status/unpaid
|
||||||
:invoice/outstanding-balance (:invoice/total invoice)
|
:invoice/outstanding-balance (:invoice/total invoice)
|
||||||
:invoice/scheduled-payment nil})]
|
:invoice/scheduled-payment nil}]]
|
||||||
(:id context))
|
(:id context))
|
||||||
|
|
||||||
(-> (d-invoices/get-by-id id)
|
(-> (d-invoices/get-by-id id)
|
||||||
@@ -377,10 +376,10 @@
|
|||||||
_ (assert-not-locked (:db/id (:invoice/client invoice)) (:invoice/date invoice))
|
_ (assert-not-locked (:db/id (:invoice/client invoice)) (:invoice/date invoice))
|
||||||
_ (assert-valid-expense-accounts (:expense_accounts args) (:db/id (:invoice/vendor invoice )))]
|
_ (assert-valid-expense-accounts (:expense_accounts args) (:db/id (:invoice/vendor invoice )))]
|
||||||
|
|
||||||
(audit-transact [`(upsert-invoice ~{:db/id invoice-id
|
(audit-transact [[:upsert-invoice {:db/id invoice-id
|
||||||
:invoice/expense-accounts (map
|
:invoice/expense-accounts (map
|
||||||
expense-account->entity
|
expense-account->entity
|
||||||
(:expense_accounts args))})]
|
(:expense_accounts args))}]]
|
||||||
(:id context))
|
(:id context))
|
||||||
(->graphql
|
(->graphql
|
||||||
(d-invoices/get-by-id (:invoice_id args))
|
(d-invoices/get-by-id (:invoice_id args))
|
||||||
@@ -469,8 +468,8 @@
|
|||||||
(log/info "Bulk coding " (count all-ids) args)
|
(log/info "Bulk coding " (count all-ids) args)
|
||||||
(audit-transact-batch
|
(audit-transact-batch
|
||||||
(map (fn [i]
|
(map (fn [i]
|
||||||
`(upsert-invoice ~{:db/id (:db/id i)
|
[:upsert-invoice {:db/id (:db/id i)
|
||||||
:invoice/expense-accounts (maybe-code-accounts i (:accounts args) locations)}))
|
:invoice/expense-accounts (maybe-code-accounts i (:accounts args) locations)}])
|
||||||
invoices)
|
invoices)
|
||||||
(:id context))
|
(:id context))
|
||||||
{:message (str "Successfully coded " (count all-ids) " invoices.")}))
|
{:message (str "Successfully coded " (count all-ids) " invoices.")}))
|
||||||
|
|||||||
@@ -27,8 +27,8 @@
|
|||||||
[clojure.data.csv :as csv]
|
[clojure.data.csv :as csv]
|
||||||
[clojure.tools.logging :as log]
|
[clojure.tools.logging :as log]
|
||||||
[com.brunobonacci.mulog :as mu]
|
[com.brunobonacci.mulog :as mu]
|
||||||
[datomic.client.api :as dc]
|
[datomic.api :as dc]
|
||||||
[iol-ion.tx :refer [random-tempid upsert-ledger]])
|
[iol-ion.tx :refer [random-tempid]])
|
||||||
(:import
|
(:import
|
||||||
(org.apache.commons.codec.binary Base64)))
|
(org.apache.commons.codec.binary Base64)))
|
||||||
|
|
||||||
@@ -132,7 +132,7 @@
|
|||||||
|
|
||||||
(defn full-ledger-for-client [client-id]
|
(defn full-ledger-for-client [client-id]
|
||||||
(->> (dc/q
|
(->> (dc/q
|
||||||
{:query {:find ['?d '?jel '?account '?location '?debit '?credit]
|
{:find ['?d '?jel '?account '?location '?debit '?credit]
|
||||||
:in ['$ '?client-id]
|
:in ['$ '?client-id]
|
||||||
:where '[[?e :journal-entry/client ?client-id]
|
:where '[[?e :journal-entry/client ?client-id]
|
||||||
[?e :journal-entry/date ?d]
|
[?e :journal-entry/date ?d]
|
||||||
@@ -149,9 +149,8 @@
|
|||||||
[(get-else $ ?jel :journal-entry-line/account :account/unknown) ?account]
|
[(get-else $ ?jel :journal-entry-line/account :account/unknown) ?account]
|
||||||
[(get-else $ ?jel :journal-entry-line/debit 0.0) ?debit ]
|
[(get-else $ ?jel :journal-entry-line/debit 0.0) ?debit ]
|
||||||
[(get-else $ ?jel :journal-entry-line/credit 0.0) ?credit]
|
[(get-else $ ?jel :journal-entry-line/credit 0.0) ?credit]
|
||||||
[(get-else $ ?jel :journal-entry-line/location "") ?location]]
|
[(get-else $ ?jel :journal-entry-line/location "") ?location]]}
|
||||||
}
|
(dc/db conn) client-id)
|
||||||
:args [(dc/db conn) client-id]})
|
|
||||||
(sort-by first)))
|
(sort-by first)))
|
||||||
|
|
||||||
(defn get-balance-sheet [context args _]
|
(defn get-balance-sheet [context args _]
|
||||||
@@ -438,8 +437,8 @@
|
|||||||
(assoc entry
|
(assoc entry
|
||||||
:status :success
|
:status :success
|
||||||
:tx
|
:tx
|
||||||
`(upsert-ledger
|
[:upsert-ledger
|
||||||
~(remove-nils
|
(remove-nils
|
||||||
{:journal-entry/source (:source entry)
|
{:journal-entry/source (:source entry)
|
||||||
:journal-entry/client [:client/code (:client_code entry)]
|
:journal-entry/client [:client/code (:client_code entry)]
|
||||||
:journal-entry/date (coerce/to-date (parse/parse-value :clj-time "MM/dd/yyyy" (:date entry)))
|
:journal-entry/date (coerce/to-date (parse/parse-value :clj-time "MM/dd/yyyy" (:date entry)))
|
||||||
@@ -502,7 +501,7 @@
|
|||||||
(not matching-account) (assoc :journal-entry-line/account [:bank-account/code (:account_identifier ea)]))))))
|
(not matching-account) (assoc :journal-entry-line/account [:bank-account/code (:account_identifier ea)]))))))
|
||||||
(:line_items entry))
|
(:line_items entry))
|
||||||
|
|
||||||
:journal-entry/cleared true}))))))
|
:journal-entry/cleared true})]))))
|
||||||
(:entries args))))
|
(:entries args))))
|
||||||
errors (filter #(= (:status %) :error) transaction)
|
errors (filter #(= (:status %) :error) transaction)
|
||||||
ignored (filter #(= (:status %) :ignored) transaction)
|
ignored (filter #(= (:status %) :ignored) transaction)
|
||||||
|
|||||||
@@ -7,7 +7,8 @@
|
|||||||
conn
|
conn
|
||||||
merge-query
|
merge-query
|
||||||
pull-attr
|
pull-attr
|
||||||
pull-many-by-id]]
|
pull-many-by-id
|
||||||
|
query2]]
|
||||||
[auto-ap.graphql.utils
|
[auto-ap.graphql.utils
|
||||||
:refer [->graphql
|
:refer [->graphql
|
||||||
<-graphql
|
<-graphql
|
||||||
@@ -20,7 +21,7 @@
|
|||||||
[clj-time.coerce :as coerce]
|
[clj-time.coerce :as coerce]
|
||||||
[clj-time.core :as time]
|
[clj-time.core :as time]
|
||||||
[clojure.tools.logging :as log]
|
[clojure.tools.logging :as log]
|
||||||
[datomic.client.api :as dc]))
|
[datomic.api :as dc]))
|
||||||
|
|
||||||
(defn plaid-link-token [context value _]
|
(defn plaid-link-token [context value _]
|
||||||
(when-not (:client_id value)
|
(when-not (:client_id value)
|
||||||
@@ -46,8 +47,7 @@
|
|||||||
:plaid-item/last-updated (coerce/to-date (time/now))
|
:plaid-item/last-updated (coerce/to-date (time/now))
|
||||||
:db/id "plaid-item"}]
|
:db/id "plaid-item"}]
|
||||||
|
|
||||||
(dc/transact conn {:tx-data
|
@(dc/transact conn (->> (:accounts account-result)
|
||||||
(->> (:accounts account-result)
|
|
||||||
(map (fn [a]
|
(map (fn [a]
|
||||||
(let [balance (some-> a :balances :current (* 0.01))]
|
(let [balance (some-> a :balances :current (* 0.01))]
|
||||||
(cond-> {:plaid-account/external-id (:account_id a)
|
(cond-> {:plaid-account/external-id (:account_id a)
|
||||||
@@ -55,7 +55,7 @@
|
|||||||
:plaid-account/name (str (:name a) " " (:mask a))
|
:plaid-account/name (str (:name a) " " (:mask a))
|
||||||
:plaid-item/_accounts "plaid-item"}
|
:plaid-item/_accounts "plaid-item"}
|
||||||
balance (assoc :plaid-account/balance balance)))))
|
balance (assoc :plaid-account/balance balance)))))
|
||||||
(into [item]))})
|
(into [item])))
|
||||||
(log/info "Access token was " access-token)
|
(log/info "Access token was " access-token)
|
||||||
{:message (str "Plaid linked successfully.")}))
|
{:message (str "Plaid linked successfully.")}))
|
||||||
|
|
||||||
@@ -93,8 +93,7 @@
|
|||||||
(merge-query {:query {:find ['?e]
|
(merge-query {:query {:find ['?e]
|
||||||
:where ['[?e :plaid-item/external-id]]}}))]
|
:where ['[?e :plaid-item/external-id]]}}))]
|
||||||
|
|
||||||
(cond->> query
|
(cond->> (query2 query)
|
||||||
true (dc/q)
|
|
||||||
true (apply-sort-3 args)
|
true (apply-sort-3 args)
|
||||||
true (apply-pagination args))))
|
true (apply-pagination args))))
|
||||||
|
|
||||||
@@ -126,7 +125,7 @@
|
|||||||
(defn delete-plaid-item [context args _]
|
(defn delete-plaid-item [context args _]
|
||||||
(assert-admin (:id context))
|
(assert-admin (:id context))
|
||||||
(assert-present args :id)
|
(assert-present args :id)
|
||||||
(dc/transact conn {:tx-data [[:db/retractEntity (:id args)]]})
|
@(dc/transact conn [[:db/retractEntity (:id args)]])
|
||||||
{:message "Item deleted."})
|
{:message "Item deleted."})
|
||||||
|
|
||||||
(defn attach [schema]
|
(defn attach [schema]
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
[auto-ap.graphql.utils
|
[auto-ap.graphql.utils
|
||||||
:refer [<-graphql assert-admin attach-tracing-resolvers result->page]]
|
:refer [<-graphql assert-admin attach-tracing-resolvers result->page]]
|
||||||
[config.core :refer [env]]
|
[config.core :refer [env]]
|
||||||
[datomic.client.api :as dc]))
|
[datomic.api :as dc]))
|
||||||
|
|
||||||
(defn get-report-page [context args _]
|
(defn get-report-page [context args _]
|
||||||
(let [args (assoc args :id (:id context))
|
(let [args (assoc args :id (:id context))
|
||||||
@@ -25,7 +25,7 @@
|
|||||||
(when id-to-delete
|
(when id-to-delete
|
||||||
(s3/delete-object :bucket-name (:data-bucket env)
|
(s3/delete-object :bucket-name (:data-bucket env)
|
||||||
:key key)
|
:key key)
|
||||||
(dc/transact conn {:tx-data [[:db/retractEntity id-to-delete]]}))
|
@(dc/transact conn [[:db/retractEntity id-to-delete]]))
|
||||||
{:message (format "deleted %s successfully" key)}))
|
{:message (format "deleted %s successfully" key)}))
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
(ns auto-ap.graphql.transaction-rules
|
(ns auto-ap.graphql.transaction-rules
|
||||||
(:require
|
(:require
|
||||||
[auto-ap.datomic :refer [audit-transact conn merge-query]]
|
[auto-ap.datomic :refer [audit-transact conn merge-query query2]]
|
||||||
[iol-ion.tx :refer [upsert-entity random-tempid]]
|
|
||||||
[auto-ap.datomic.transaction-rules :as tr]
|
[auto-ap.datomic.transaction-rules :as tr]
|
||||||
[auto-ap.datomic.transactions :as d-transactions]
|
[auto-ap.datomic.transactions :as d-transactions]
|
||||||
[auto-ap.graphql.utils
|
[auto-ap.graphql.utils
|
||||||
@@ -16,8 +15,9 @@
|
|||||||
[auto-ap.utils :refer [dollars=]]
|
[auto-ap.utils :refer [dollars=]]
|
||||||
[clj-time.coerce :as c]
|
[clj-time.coerce :as c]
|
||||||
[clojure.string :as str]
|
[clojure.string :as str]
|
||||||
[datomic.client.api :as dc]
|
[com.brunobonacci.mulog :as mu]
|
||||||
[com.brunobonacci.mulog :as mu]))
|
[datomic.api :as dc]
|
||||||
|
[iol-ion.tx :refer [random-tempid]]))
|
||||||
|
|
||||||
(defn get-transaction-rule-page [context args _]
|
(defn get-transaction-rule-page [context args _]
|
||||||
(let [args (assoc args :id (:id context))
|
(let [args (assoc args :id (:id context))
|
||||||
@@ -82,7 +82,7 @@
|
|||||||
rule-id (if id
|
rule-id (if id
|
||||||
id
|
id
|
||||||
"transaction-rule")
|
"transaction-rule")
|
||||||
transaction [`(upsert-entity ~#:transaction-rule {:db/id (or rule-id (random-tempid))
|
transaction [[:upsert-entity #:transaction-rule {:db/id (or rule-id (random-tempid))
|
||||||
:description description
|
:description description
|
||||||
:note note
|
:note note
|
||||||
:client client_id
|
:client client_id
|
||||||
@@ -98,7 +98,7 @@
|
|||||||
name
|
name
|
||||||
snake->kebab
|
snake->kebab
|
||||||
(keyword "transaction-approval-status"))
|
(keyword "transaction-approval-status"))
|
||||||
:transaction-rule/accounts (map transaction-rule-account->entity accounts)})]
|
:transaction-rule/accounts (map transaction-rule-account->entity accounts)}]]
|
||||||
|
|
||||||
|
|
||||||
transaction-result (audit-transact transaction (:id context))]
|
transaction-result (audit-transact transaction (:id context))]
|
||||||
@@ -108,16 +108,13 @@
|
|||||||
(->graphql))))
|
(->graphql))))
|
||||||
|
|
||||||
(defn -test-transaction-rule [id {:keys [:transaction-rule/description :transaction-rule/client :transaction-rule/bank-account :transaction-rule/amount-lte :transaction-rule/amount-gte :transaction-rule/dom-lte :transaction-rule/dom-gte :transaction-rule/yodlee-merchant]} include-coded? count]
|
(defn -test-transaction-rule [id {:keys [:transaction-rule/description :transaction-rule/client :transaction-rule/bank-account :transaction-rule/amount-lte :transaction-rule/amount-gte :transaction-rule/dom-lte :transaction-rule/dom-gte :transaction-rule/yodlee-merchant]} include-coded? count]
|
||||||
(->>
|
(let [query (cond-> {:query {:find ['(pull ?e [* {:transaction/client [:client/name]
|
||||||
(dc/q
|
|
||||||
(cond-> {:query {:find ['(pull ?e [* {:transaction/client [:client/name]
|
|
||||||
:transaction/bank-account [:bank-account/name]
|
:transaction/bank-account [:bank-account/name]
|
||||||
:transaction/payment [:db/id]}
|
:transaction/payment [:db/id]}
|
||||||
])]
|
])]
|
||||||
:in ['$ ]
|
:in ['$ ]
|
||||||
:where []}
|
:where []}
|
||||||
:args [(dc/db conn)]
|
:args [(dc/db conn)]}
|
||||||
:timeout 55000}
|
|
||||||
description
|
description
|
||||||
(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]]}
|
||||||
@@ -179,8 +176,9 @@
|
|||||||
[(missing? $ ?e :transaction/approval-status)]]]}})
|
[(missing? $ ?e :transaction/approval-status)]]]}})
|
||||||
|
|
||||||
true
|
true
|
||||||
(merge-query {:query {:where ['[?e :transaction/id]]}})))
|
(merge-query {:query {:where ['[?e :transaction/id]]}}))]
|
||||||
|
(->>
|
||||||
|
(query2 query)
|
||||||
(transduce (comp
|
(transduce (comp
|
||||||
(take (or count 15))
|
(take (or count 15))
|
||||||
(map first)
|
(map first)
|
||||||
@@ -188,7 +186,7 @@
|
|||||||
(map (fn [x]
|
(map (fn [x]
|
||||||
(update x :transaction/date c/from-date)))
|
(update x :transaction/date c/from-date)))
|
||||||
(map ->graphql))
|
(map ->graphql))
|
||||||
conj [])))
|
conj []))))
|
||||||
|
|
||||||
(defn test-transaction-rule [{:keys [id]} {{:keys [description client_id bank_account_id amount_lte amount_gte dom_lte dom_gte yodlee_merchant_id]} :transaction_rule} _]
|
(defn test-transaction-rule [{:keys [id]} {{:keys [description client_id bank_account_id amount_lte amount_gte dom_lte dom_gte yodlee_merchant_id]} :transaction_rule} _]
|
||||||
(assert-admin id)
|
(assert-admin id)
|
||||||
|
|||||||
@@ -25,8 +25,8 @@
|
|||||||
[clojure.set :as set]
|
[clojure.set :as set]
|
||||||
[clojure.string :as str]
|
[clojure.string :as str]
|
||||||
[clojure.tools.logging :as log]
|
[clojure.tools.logging :as log]
|
||||||
[datomic.client.api :as dc]
|
[datomic.api :as dc]
|
||||||
[iol-ion.tx :refer [random-tempid upsert-transaction]]
|
[iol-ion.tx :refer [random-tempid]]
|
||||||
[com.brunobonacci.mulog :as mu]))
|
[com.brunobonacci.mulog :as mu]))
|
||||||
|
|
||||||
(def approval-status->graphql (ident->enum-f :transaction/approval-status))
|
(def approval-status->graphql (ident->enum-f :transaction/approval-status))
|
||||||
@@ -92,8 +92,8 @@
|
|||||||
(audit-transact-batch
|
(audit-transact-batch
|
||||||
(->> all-ids
|
(->> all-ids
|
||||||
(mapv (fn [t]
|
(mapv (fn [t]
|
||||||
`(upsert-transaction ~{:db/id t
|
[:upsert-transaction {:db/id t
|
||||||
:transaction/approval-status (enum->keyword (:status args) "transaction-approval-status")}))))
|
:transaction/approval-status (enum->keyword (:status args) "transaction-approval-status")}])))
|
||||||
|
|
||||||
(:id context))
|
(:id context))
|
||||||
{:message (str "Succesfully changed " (count all-ids) " transactions to be " (name (:status args) ) ".")}))
|
{:message (str "Succesfully changed " (count all-ids) " transactions to be " (name (:status args) ) ".")}))
|
||||||
@@ -172,10 +172,10 @@
|
|||||||
(log/info "Bulk coding " (count all-ids) args)
|
(log/info "Bulk coding " (count all-ids) args)
|
||||||
(audit-transact-batch
|
(audit-transact-batch
|
||||||
(map (fn [i]
|
(map (fn [i]
|
||||||
`(upsert-transaction ~(cond-> i
|
[:upsert-transaction (cond-> i
|
||||||
(:approval_status args) (assoc :transaction/approval-status (enum->keyword (:approval_status args) "transaction-approval-status"))
|
(:approval_status args) (assoc :transaction/approval-status (enum->keyword (:approval_status args) "transaction-approval-status"))
|
||||||
(:vendor args) (assoc :transaction/vendor (:vendor args))
|
(:vendor args) (assoc :transaction/vendor (:vendor args))
|
||||||
(seq (:accounts args)) (assoc :transaction/accounts (maybe-code-accounts i (:accounts args) locations)))))
|
(seq (:accounts args)) (assoc :transaction/accounts (maybe-code-accounts i (:accounts args) locations)))])
|
||||||
transactions)
|
transactions)
|
||||||
(:id context))
|
(:id context))
|
||||||
{:message (str "Successfully coded " (count all-ids) " transactions.")}))
|
{:message (str "Successfully coded " (count all-ids) " transactions.")}))
|
||||||
@@ -252,13 +252,12 @@
|
|||||||
(assert-not-locked (:db/id (:transaction/client transaction)) (-> transaction :transaction/payment :payment/date)))
|
(assert-not-locked (:db/id (:transaction/client transaction)) (-> transaction :transaction/payment :payment/date)))
|
||||||
_ (log/info "Unlinking" transaction)
|
_ (log/info "Unlinking" transaction)
|
||||||
payment (-> transaction :transaction/payment )
|
payment (-> transaction :transaction/payment )
|
||||||
is-autopay-payment? (some->> (doto (dc/q {:query {:find ['?sp]
|
is-autopay-payment? (some->> (dc/q {:find ['?sp]
|
||||||
:in ['$ '?payment]
|
:in ['$ '?payment]
|
||||||
:where ['[?ip :invoice-payment/payment ?payment]
|
:where ['[?ip :invoice-payment/payment ?payment]
|
||||||
'[?ip :invoice-payment/invoice ?i]
|
'[?ip :invoice-payment/invoice ?i]
|
||||||
'[(get-else $ ?i :invoice/scheduled-payment "N/A") ?sp]]}
|
'[(get-else $ ?i :invoice/scheduled-payment "N/A") ?sp]]}
|
||||||
:args [(dc/db conn) (:db/id payment)]})
|
(dc/db conn) (:db/id payment))
|
||||||
log/info)
|
|
||||||
seq
|
seq
|
||||||
(map first)
|
(map first)
|
||||||
(every? #(instance? java.util.Date %)))
|
(every? #(instance? java.util.Date %)))
|
||||||
@@ -273,33 +272,34 @@
|
|||||||
(audit-transact
|
(audit-transact
|
||||||
(-> [{:db/id (:db/id payment)
|
(-> [{:db/id (:db/id payment)
|
||||||
:payment/status :payment-status/pending}
|
:payment/status :payment-status/pending}
|
||||||
`(upsert-transaction
|
[:upsert-transaction
|
||||||
~{:db/id transaction-id
|
{:db/id transaction-id
|
||||||
:transaction/approval-status :transaction-approval-status/unapproved
|
:transaction/approval-status :transaction-approval-status/unapproved
|
||||||
:transaction/payment nil
|
:transaction/payment nil
|
||||||
:transaction/vendor nil
|
:transaction/vendor nil
|
||||||
:transaction/location nil
|
:transaction/location nil
|
||||||
:transaction/accounts nil})
|
:transaction/accounts nil}]
|
||||||
|
|
||||||
[:db/retractEntity (:db/id payment) ]]
|
[:db/retractEntity (:db/id payment) ]]
|
||||||
|
|
||||||
(into (map (fn [[invoice-payment]]
|
(into (map (fn [[invoice-payment]]
|
||||||
[:db/retractEntity invoice-payment])
|
[:db/retractEntity invoice-payment])
|
||||||
(dc/q {:query {:find ['?ip]
|
(dc/q {:find ['?ip]
|
||||||
:in ['$ '?p]
|
:in ['$ '?p]
|
||||||
:where ['[?ip :invoice-payment/payment ?p]]}
|
:where ['[?ip :invoice-payment/payment ?p]]}
|
||||||
:args [(dc/db conn) (:db/id payment)]} ))))
|
(dc/db conn)
|
||||||
|
(:db/id payment) ))))
|
||||||
(:id context))
|
(:id context))
|
||||||
(audit-transact
|
(audit-transact
|
||||||
[{:db/id (:db/id payment)
|
[{:db/id (:db/id payment)
|
||||||
:payment/status :payment-status/pending}
|
:payment/status :payment-status/pending}
|
||||||
`(upsert-transaction
|
[:upsert-transaction
|
||||||
~{:db/id transaction-id
|
{:db/id transaction-id
|
||||||
:transaction/approval-status :transaction-approval-status/unapproved
|
:transaction/approval-status :transaction-approval-status/unapproved
|
||||||
:transaction/payment nil
|
:transaction/payment nil
|
||||||
:transaction/vendor nil
|
:transaction/vendor nil
|
||||||
:transaction/location nil
|
:transaction/location nil
|
||||||
:transaction/accounts nil})]
|
:transaction/accounts nil}]]
|
||||||
(:id context)))
|
(:id context)))
|
||||||
(-> (d-transactions/get-by-id transaction-id)
|
(-> (d-transactions/get-by-id transaction-id)
|
||||||
approval-status->graphql
|
approval-status->graphql
|
||||||
@@ -360,14 +360,14 @@
|
|||||||
(when missing-locations
|
(when missing-locations
|
||||||
(throw (ex-info (str "Location '" (str/join ", " missing-locations) "' not found on client.") {})) )
|
(throw (ex-info (str "Location '" (str/join ", " missing-locations) "' not found on client.") {})) )
|
||||||
|
|
||||||
(audit-transact [`(upsert-transaction ~{:db/id id
|
(audit-transact [[:upsert-transaction {:db/id id
|
||||||
:transaction/vendor vendor_id
|
:transaction/vendor vendor_id
|
||||||
:transaction/approval-status (some->> approval_status
|
:transaction/approval-status (some->> approval_status
|
||||||
name
|
name
|
||||||
snake->kebab
|
snake->kebab
|
||||||
(keyword "transaction-approval-status"))
|
(keyword "transaction-approval-status"))
|
||||||
:transaction/accounts (map transaction-account->entity accounts)
|
:transaction/accounts (map transaction-account->entity accounts)
|
||||||
:transaction/forecast-match forecast_match})]
|
:transaction/forecast-match forecast_match}]]
|
||||||
(:id context))
|
(:id context))
|
||||||
(-> (d-transactions/get-by-id id)
|
(-> (d-transactions/get-by-id id)
|
||||||
approval-status->graphql
|
approval-status->graphql
|
||||||
@@ -392,8 +392,8 @@
|
|||||||
:payment/date (coerce/to-date (first (sort [(:payment/date payment)
|
:payment/date (coerce/to-date (first (sort [(:payment/date payment)
|
||||||
(:transaction/date transaction)])))}
|
(:transaction/date transaction)])))}
|
||||||
|
|
||||||
`(upsert-transaction
|
[:upsert-transaction
|
||||||
~{:db/id (:db/id transaction)
|
{:db/id (:db/id transaction)
|
||||||
:transaction/payment (:db/id payment)
|
:transaction/payment (:db/id payment)
|
||||||
:transaction/vendor (:db/id (:payment/vendor payment))
|
:transaction/vendor (:db/id (:payment/vendor payment))
|
||||||
:transaction/location "A"
|
:transaction/location "A"
|
||||||
@@ -401,7 +401,7 @@
|
|||||||
:transaction/accounts [{:db/id (random-tempid)
|
:transaction/accounts [{:db/id (random-tempid)
|
||||||
:transaction-account/account (:db/id (a/get-account-by-numeric-code-and-sets 21000 ["default"]))
|
:transaction-account/account (:db/id (a/get-account-by-numeric-code-and-sets 21000 ["default"]))
|
||||||
:transaction-account/location "A"
|
:transaction-account/location "A"
|
||||||
:transaction-account/amount (Math/abs (:transaction/amount transaction))}]})])
|
:transaction-account/amount (Math/abs (:transaction/amount transaction))}]}]])
|
||||||
(:id context)))
|
(:id context)))
|
||||||
(-> (d-transactions/get-by-id transaction_id)
|
(-> (d-transactions/get-by-id transaction_id)
|
||||||
approval-status->graphql
|
approval-status->graphql
|
||||||
@@ -509,13 +509,13 @@
|
|||||||
|
|
||||||
(throw (ex-info "Transaction already associated with a payment" {:validation-error "Transaction already associated with a payment"}))))
|
(throw (ex-info "Transaction already associated with a payment" {:validation-error "Transaction already associated with a payment"}))))
|
||||||
(audit-transact (mapv (fn [t]
|
(audit-transact (mapv (fn [t]
|
||||||
`(upsert-transaction
|
[:upsert-transaction
|
||||||
~(remove-nils (rm/apply-rule {:db/id (:db/id t)
|
(remove-nils (rm/apply-rule {:db/id (:db/id t)
|
||||||
:transaction/amount (:transaction/amount t)}
|
:transaction/amount (:transaction/amount t)}
|
||||||
transaction-rule
|
transaction-rule
|
||||||
|
|
||||||
(or (-> t :transaction/bank-account :bank-account/locations)
|
(or (-> t :transaction/bank-account :bank-account/locations)
|
||||||
(-> t :transaction/client :client/locations))))))
|
(-> t :transaction/client :client/locations))))])
|
||||||
transactions)
|
transactions)
|
||||||
(:id context))
|
(:id context))
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
[clj-time.coerce :as coerce]
|
[clj-time.coerce :as coerce]
|
||||||
[auto-ap.time :as atime]
|
[auto-ap.time :as atime]
|
||||||
[buddy.auth :refer [throw-unauthorized]]
|
[buddy.auth :refer [throw-unauthorized]]
|
||||||
[datomic.client.api :as dc]
|
[datomic.api :as dc]
|
||||||
[clojure.walk :as walk]
|
[clojure.walk :as walk]
|
||||||
[com.walmartlabs.lacinia.util :refer [attach-resolvers]]
|
[com.walmartlabs.lacinia.util :refer [attach-resolvers]]
|
||||||
[clojure.tools.logging :as log]
|
[clojure.tools.logging :as log]
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
(ns auto-ap.graphql.vendors
|
(ns auto-ap.graphql.vendors
|
||||||
(:require
|
(:require
|
||||||
[auto-ap.datomic :refer [audit-transact conn pull-attr remove-nils]]
|
[auto-ap.datomic :refer [audit-transact conn pull-attr remove-nils]]
|
||||||
[iol-ion.tx :refer [upsert-entity random-tempid]]
|
[iol-ion.tx :refer [random-tempid]]
|
||||||
[auto-ap.datomic.vendors :as d-vendors]
|
[auto-ap.datomic.vendors :as d-vendors]
|
||||||
[auto-ap.graphql.utils
|
[auto-ap.graphql.utils
|
||||||
:refer [->graphql
|
:refer [->graphql
|
||||||
@@ -19,7 +19,7 @@
|
|||||||
[manifold.executor :as ex]
|
[manifold.executor :as ex]
|
||||||
[manifold.deferred :as de]
|
[manifold.deferred :as de]
|
||||||
[clojure.tools.logging :as log]
|
[clojure.tools.logging :as log]
|
||||||
[datomic.client.api :as dc]
|
[datomic.api :as dc]
|
||||||
[yang.scheduler :as scheduler]
|
[yang.scheduler :as scheduler]
|
||||||
[mount.core :as mount]
|
[mount.core :as mount]
|
||||||
[clj-time.core :as time]
|
[clj-time.core :as time]
|
||||||
@@ -87,7 +87,7 @@
|
|||||||
:dom (:dom ao)
|
:dom (:dom ao)
|
||||||
:db/id (or (:id ao) (random-tempid))})
|
:db/id (or (:id ao) (random-tempid))})
|
||||||
schedule_payment_dom)
|
schedule_payment_dom)
|
||||||
transaction `(upsert-entity ~(cond-> #:vendor {:db/id (if id
|
transaction [:upsert-entity (cond-> #:vendor {:db/id (if id
|
||||||
id
|
id
|
||||||
"vendor")
|
"vendor")
|
||||||
:name name
|
:name name
|
||||||
@@ -135,7 +135,7 @@
|
|||||||
:vendor/account-overrides account-overrides
|
:vendor/account-overrides account-overrides
|
||||||
:vendor/terms-overrides terms-overrides
|
:vendor/terms-overrides terms-overrides
|
||||||
:vendor/schedule-payment-dom schedule-payment-dom
|
:vendor/schedule-payment-dom schedule-payment-dom
|
||||||
:vendor/automatically-paid-when-due (:automatically_paid_when_due in))))
|
:vendor/automatically-paid-when-due (:automatically_paid_when_due in)))]
|
||||||
|
|
||||||
|
|
||||||
transaction-result (audit-transact [transaction] (:id context))]
|
transaction-result (audit-transact [transaction] (:id context))]
|
||||||
@@ -145,11 +145,12 @@
|
|||||||
(->graphql))))
|
(->graphql))))
|
||||||
|
|
||||||
(defn merge-vendors [context {:keys [from to]} _]
|
(defn merge-vendors [context {:keys [from to]} _]
|
||||||
(let [transaction (->> (dc/q {:query {:find '[?x ?a2]
|
(let [transaction (->> (dc/q {:find '[?x ?a2]
|
||||||
:in '[$ ?vendor-from ]
|
:in '[$ ?vendor-from ]
|
||||||
:where ['[?x ?a ?vendor-from]
|
:where ['[?x ?a ?vendor-from]
|
||||||
'[?a :db/ident ?a2]]}
|
'[?a :db/ident ?a2]]}
|
||||||
:args [(dc/db conn) from]})
|
(dc/db conn)
|
||||||
|
from)
|
||||||
(mapcat (fn [[src attr]]
|
(mapcat (fn [[src attr]]
|
||||||
|
|
||||||
[[:db/retract src attr from]
|
[[:db/retract src attr from]
|
||||||
@@ -195,10 +196,10 @@
|
|||||||
(de/future-with
|
(de/future-with
|
||||||
single-thread
|
single-thread
|
||||||
(search/full-index-query
|
(search/full-index-query
|
||||||
(for [[result] (dc/qseq '[:find (pull ?v [:vendor/search-terms :db/id :vendor/name :vendor/hidden])
|
(for [[result] (dc/qseq {:query '[:find (pull ?v [:vendor/search-terms :db/id :vendor/name :vendor/hidden])
|
||||||
:in $
|
:in $
|
||||||
:where [?v :vendor/search-terms ]]
|
:where [?v :vendor/search-terms ]]
|
||||||
(dc/db conn))]
|
:args [(dc/db conn)]})]
|
||||||
{:id (:db/id result)
|
{:id (:db/id result)
|
||||||
:text (or (first (:vendor/search-terms result))
|
:text (or (first (:vendor/search-terms result))
|
||||||
(:vendor/name result))
|
(:vendor/name result))
|
||||||
@@ -216,12 +217,11 @@
|
|||||||
_ (mu/log ::indexing
|
_ (mu/log ::indexing
|
||||||
:last-run last-run-basis-value
|
:last-run last-run-basis-value
|
||||||
:starting-from (:basisT db))
|
:starting-from (:basisT db))
|
||||||
results (for [[result] (dc/qseq '[:find (pull ?v [:vendor/search-terms :db/id :vendor/name :vendor/hidden])
|
results (for [[result] (dc/qseq {:query '[:find (pull ?v [:vendor/search-terms :db/id :vendor/name :vendor/hidden])
|
||||||
:in $ $$
|
:in $ $$
|
||||||
:where [$ ?v :vendor/name ]
|
:where [$ ?v :vendor/name ]
|
||||||
[$$ ?v]]
|
[$$ ?v]]
|
||||||
db
|
:args [db recent]})]
|
||||||
recent)]
|
|
||||||
{:id (:db/id result)
|
{:id (:db/id result)
|
||||||
:text (or (first (:vendor/search-terms result))
|
:text (or (first (:vendor/search-terms result))
|
||||||
(:vendor/name result))
|
(:vendor/name result))
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
(:require
|
(:require
|
||||||
[auto-ap.datomic :refer [conn pull-ref random-tempid]]
|
[auto-ap.datomic :refer [conn pull-ref random-tempid]]
|
||||||
[clojure.tools.logging :as log]
|
[clojure.tools.logging :as log]
|
||||||
[datomic.client.api :as dc]))
|
[datomic.api :as dc]))
|
||||||
|
|
||||||
(defn bank-account->integration-id [bank-account]
|
(defn bank-account->integration-id [bank-account]
|
||||||
(or (pull-ref (dc/db conn) :bank-account/integration-status bank-account)
|
(or (pull-ref (dc/db conn) :bank-account/integration-status bank-account)
|
||||||
@@ -11,19 +11,19 @@
|
|||||||
(defn wrap-integration [f bank-account]
|
(defn wrap-integration [f bank-account]
|
||||||
(try
|
(try
|
||||||
(let [result (f)]
|
(let [result (f)]
|
||||||
(dc/transact conn {:tx-data [{:db/id bank-account
|
@(dc/transact conn [{:db/id bank-account
|
||||||
:bank-account/integration-status
|
:bank-account/integration-status
|
||||||
{:db/id (bank-account->integration-id bank-account)
|
{:db/id (bank-account->integration-id bank-account)
|
||||||
:integration-status/state :integration-state/success
|
:integration-status/state :integration-state/success
|
||||||
:integration-status/last-attempt (java.util.Date.)
|
:integration-status/last-attempt (java.util.Date.)
|
||||||
:integration-status/last-updated (java.util.Date.)}}]})
|
:integration-status/last-updated (java.util.Date.)}}])
|
||||||
result)
|
result)
|
||||||
(catch Exception e
|
(catch Exception e
|
||||||
(dc/transact conn {:tx-data [{:db/id bank-account
|
@(dc/transact conn [{:db/id bank-account
|
||||||
:bank-account/integration-status
|
:bank-account/integration-status
|
||||||
{:db/id (bank-account->integration-id bank-account)
|
{:db/id (bank-account->integration-id bank-account)
|
||||||
:integration-status/state :integration-state/failed
|
:integration-status/state :integration-state/failed
|
||||||
:integration-status/last-attempt (java.util.Date.)
|
:integration-status/last-attempt (java.util.Date.)
|
||||||
:integration-status/message (.getMessage e)}}]})
|
:integration-status/message (.getMessage e)}}])
|
||||||
(log/warn e)
|
(log/warn e)
|
||||||
nil)))
|
nil)))
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
[clojure.string :as str]
|
[clojure.string :as str]
|
||||||
[clojure.tools.logging :as log]
|
[clojure.tools.logging :as log]
|
||||||
[com.unbounce.dogstatsd.core :as statsd]
|
[com.unbounce.dogstatsd.core :as statsd]
|
||||||
[datomic.client.api :as dc]
|
[datomic.api :as dc]
|
||||||
[mount.core :as mount]
|
[mount.core :as mount]
|
||||||
[yang.scheduler :as scheduler]))
|
[yang.scheduler :as scheduler]))
|
||||||
|
|
||||||
@@ -78,8 +78,8 @@
|
|||||||
(defn upsert-accounts []
|
(defn upsert-accounts []
|
||||||
(let [token (i/get-fresh-access-token)
|
(let [token (i/get-fresh-access-token)
|
||||||
bank-accounts (i/get-bank-accounts token)]
|
bank-accounts (i/get-bank-accounts token)]
|
||||||
(dc/transact conn {:tx-data (mapv
|
@(dc/transact conn (mapv
|
||||||
(fn [ba]
|
(fn [ba]
|
||||||
{:intuit-bank-account/external-id (:name ba)
|
{:intuit-bank-account/external-id (:name ba)
|
||||||
:intuit-bank-account/name (:name ba)})
|
:intuit-bank-account/name (:name ba)})
|
||||||
bank-accounts)})))
|
bank-accounts))))
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
[auto-ap.import.transactions :as t]
|
[auto-ap.import.transactions :as t]
|
||||||
[clj-time.coerce :as coerce]
|
[clj-time.coerce :as coerce]
|
||||||
[clojure.data.csv :as csv]
|
[clojure.data.csv :as csv]
|
||||||
[datomic.client.api :as dc]
|
[datomic.api :as dc]
|
||||||
[unilog.context :as lc]))
|
[unilog.context :as lc]))
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
[auto-ap.utils :refer [allow-once by]]
|
[auto-ap.utils :refer [allow-once by]]
|
||||||
[clj-time.coerce :as coerce]
|
[clj-time.coerce :as coerce]
|
||||||
[clj-time.core :as time]
|
[clj-time.core :as time]
|
||||||
[datomic.client.api :as dc]
|
[datomic.api :as dc]
|
||||||
[digest :as di]
|
[digest :as di]
|
||||||
[unilog.context :as lc]))
|
[unilog.context :as lc]))
|
||||||
|
|
||||||
|
|||||||
@@ -12,9 +12,8 @@
|
|||||||
[clj-time.core :as t]
|
[clj-time.core :as t]
|
||||||
[clojure.core.cache :as cache]
|
[clojure.core.cache :as cache]
|
||||||
[clojure.tools.logging :as log]
|
[clojure.tools.logging :as log]
|
||||||
[datomic.client.api :as dc]
|
[datomic.api :as dc]
|
||||||
[digest :as di]
|
[digest :as di]))
|
||||||
[iol-ion.tx :refer [upsert-invoice upsert-transaction]]))
|
|
||||||
|
|
||||||
(defn rough-match [client-id bank-account-id amount]
|
(defn rough-match [client-id bank-account-id amount]
|
||||||
(if (and client-id bank-account-id amount)
|
(if (and client-id bank-account-id amount)
|
||||||
@@ -56,7 +55,7 @@
|
|||||||
|
|
||||||
(defn match-transaction-to-unfulfilled-autopayments [amount client-id]
|
(defn match-transaction-to-unfulfilled-autopayments [amount client-id]
|
||||||
(log/info "trying to find uncleared autopay invoices")
|
(log/info "trying to find uncleared autopay invoices")
|
||||||
(let [candidate-invoices-vendor-groups (->> (dc/q {:query {:find ['?vendor-id '?e '?total '?sd]
|
(let [candidate-invoices-vendor-groups (->> (dc/q {:find ['?vendor-id '?e '?total '?sd]
|
||||||
:in ['$ '?client-id]
|
:in ['$ '?client-id]
|
||||||
:where ['[?e :invoice/client ?client-id]
|
:where ['[?e :invoice/client ?client-id]
|
||||||
'[?e :invoice/scheduled-payment ?sd]
|
'[?e :invoice/scheduled-payment ?sd]
|
||||||
@@ -64,7 +63,7 @@
|
|||||||
'(not [_ :invoice-payment/invoice ?e])
|
'(not [_ :invoice-payment/invoice ?e])
|
||||||
'[?e :invoice/vendor ?vendor-id]
|
'[?e :invoice/vendor ?vendor-id]
|
||||||
'[?e :invoice/total ?total]]}
|
'[?e :invoice/total ?total]]}
|
||||||
:args [(dc/db conn) client-id]})
|
(dc/db conn) client-id)
|
||||||
(sort-by last) ;; sort by scheduled payment date
|
(sort-by last) ;; sort by scheduled payment date
|
||||||
(group-by first) ;; group by vendors
|
(group-by first) ;; group by vendors
|
||||||
vals)
|
vals)
|
||||||
@@ -81,7 +80,7 @@
|
|||||||
|
|
||||||
(defn match-transaction-to-unpaid-invoices [amount client-id]
|
(defn match-transaction-to-unpaid-invoices [amount client-id]
|
||||||
(log/info "trying to find unpaid invoices for " client-id amount)
|
(log/info "trying to find unpaid invoices for " client-id amount)
|
||||||
(let [candidate-invoices-vendor-groups (->> (dc/q {:query {:find ['?vendor-id '?e '?outstanding-balance '?d]
|
(let [candidate-invoices-vendor-groups (->> (dc/q {:find ['?vendor-id '?e '?outstanding-balance '?d]
|
||||||
:in ['$ '?client-id]
|
:in ['$ '?client-id]
|
||||||
:where ['[?e :invoice/client ?client-id]
|
:where ['[?e :invoice/client ?client-id]
|
||||||
'[?e :invoice/status :invoice-status/unpaid]
|
'[?e :invoice/status :invoice-status/unpaid]
|
||||||
@@ -89,7 +88,7 @@
|
|||||||
'[?e :invoice/vendor ?vendor-id]
|
'[?e :invoice/vendor ?vendor-id]
|
||||||
'[?e :invoice/outstanding-balance ?outstanding-balance]
|
'[?e :invoice/outstanding-balance ?outstanding-balance]
|
||||||
'[?e :invoice/date ?d]]}
|
'[?e :invoice/date ?d]]}
|
||||||
:args [(dc/db conn) client-id]})
|
(dc/db conn) client-id)
|
||||||
(sort-by last) ;; sort by scheduled payment date
|
(sort-by last) ;; sort by scheduled payment date
|
||||||
(group-by first) ;; group by vendors
|
(group-by first) ;; group by vendors
|
||||||
vals)
|
vals)
|
||||||
@@ -112,7 +111,8 @@
|
|||||||
(defn add-new-payment [transaction [[vendor] :as invoice-payments] bank-account-id client-id]
|
(defn add-new-payment [transaction [[vendor] :as invoice-payments] bank-account-id client-id]
|
||||||
(log/info "Adding a new payment for transaction " (:transaction/id transaction) " and invoices " invoice-payments)
|
(log/info "Adding a new payment for transaction " (:transaction/id transaction) " and invoices " invoice-payments)
|
||||||
(let [payment-id (random-tempid)]
|
(let [payment-id (random-tempid)]
|
||||||
(-> [`(upsert-transaction ~(assoc transaction
|
(-> [[:upsert-transaction
|
||||||
|
(assoc transaction
|
||||||
:transaction/payment payment-id
|
:transaction/payment payment-id
|
||||||
:transaction/approval-status :transaction-approval-status/approved
|
:transaction/approval-status :transaction-approval-status/approved
|
||||||
:transaction/vendor vendor
|
:transaction/vendor vendor
|
||||||
@@ -122,7 +122,7 @@
|
|||||||
{:db/id (random-tempid)
|
{:db/id (random-tempid)
|
||||||
:account (:db/id (a/get-account-by-numeric-code-and-sets 21000 ["default"]))
|
:account (:db/id (a/get-account-by-numeric-code-and-sets 21000 ["default"]))
|
||||||
:location "A"
|
:location "A"
|
||||||
:amount (Math/abs (:transaction/amount transaction))}]))]
|
:amount (Math/abs (:transaction/amount transaction))}])]]
|
||||||
|
|
||||||
(conj {:payment/bank-account bank-account-id
|
(conj {:payment/bank-account bank-account-id
|
||||||
:payment/client client-id
|
:payment/client client-id
|
||||||
@@ -136,9 +136,9 @@
|
|||||||
[{:invoice-payment/invoice invoice-id
|
[{:invoice-payment/invoice invoice-id
|
||||||
:invoice-payment/payment payment-id
|
:invoice-payment/payment payment-id
|
||||||
:invoice-payment/amount invoice-amount}
|
:invoice-payment/amount invoice-amount}
|
||||||
`(upsert-invoice ~{:db/id invoice-id
|
[:upsert-invoice {:db/id invoice-id
|
||||||
:invoice/outstanding-balance 0.0
|
:invoice/outstanding-balance 0.0
|
||||||
:invoice/status :invoice-status/paid})])
|
:invoice/status :invoice-status/paid}]])
|
||||||
invoice-payments)))))
|
invoice-payments)))))
|
||||||
|
|
||||||
(defn extract-check-number [{:transaction/keys [description-original]}]
|
(defn extract-check-number [{:transaction/keys [description-original]}]
|
||||||
@@ -293,11 +293,11 @@
|
|||||||
:import-batch/not-ready 0
|
:import-batch/not-ready 0
|
||||||
:import-batch/extant 0})
|
:import-batch/extant 0})
|
||||||
extant-cache (atom (cache/ttl-cache-factory {} :ttl 60000 ))
|
extant-cache (atom (cache/ttl-cache-factory {} :ttl 60000 ))
|
||||||
import-id (get (:tempids (dc/transact conn {:tx-data [{:db/id "import-batch"
|
import-id (get (:tempids @(dc/transact conn [{:db/id "import-batch"
|
||||||
:import-batch/date (coerce/to-date (t/now))
|
:import-batch/date (coerce/to-date (t/now))
|
||||||
:import-batch/source source
|
:import-batch/source source
|
||||||
:import-batch/status :import-status/started
|
:import-batch/status :import-status/started
|
||||||
:import-batch/user-name user}]})) "import-batch")
|
:import-batch/user-name user}])) "import-batch")
|
||||||
rule-applying-function (rm/rule-applying-fn (tr/get-all))]
|
rule-applying-function (rm/rule-applying-fn (tr/get-all))]
|
||||||
(log/info "Importing transactions from " source)
|
(log/info "Importing transactions from " source)
|
||||||
|
|
||||||
@@ -317,7 +317,7 @@
|
|||||||
:error :import-batch/error
|
:error :import-batch/error
|
||||||
:not-ready :import-batch/not-ready) inc))
|
:not-ready :import-batch/not-ready) inc))
|
||||||
(when (= :import action)
|
(when (= :import action)
|
||||||
(audit-transact [`(upsert-transaction ~(transaction->txs transaction bank-account rule-applying-function))
|
(audit-transact [[:upsert-transaction (transaction->txs transaction bank-account rule-applying-function)]
|
||||||
{:db/id import-id
|
{:db/id import-id
|
||||||
:import-batch/entry (:db/id transaction)}]
|
:import-batch/entry (:db/id transaction)}]
|
||||||
{:user/name user
|
{:user/name user
|
||||||
@@ -329,14 +329,14 @@
|
|||||||
(fail! [_ error]
|
(fail! [_ error]
|
||||||
(log/errorf "Couldn't complete import %d with error." import-id)
|
(log/errorf "Couldn't complete import %d with error." import-id)
|
||||||
(log/error error)
|
(log/error error)
|
||||||
(dc/transact conn {:tx-data [(merge {:db/id import-id
|
@(dc/transact conn [(merge {:db/id import-id
|
||||||
:import-batch/status :import-status/completed
|
:import-batch/status :import-status/completed
|
||||||
:import-batch/error-message (str error)}
|
:import-batch/error-message (str error)}
|
||||||
@stats)]}))
|
@stats)]))
|
||||||
|
|
||||||
(finish! [_]
|
(finish! [_]
|
||||||
(log/infof "Finishing import batch %d for %s with stats %s " import-id (name source) (pr-str @stats))
|
(log/infof "Finishing import batch %d for %s with stats %s " import-id (name source) (pr-str @stats))
|
||||||
(dc/transact conn [(merge {:db/id import-id
|
@(dc/transact conn [(merge {:db/id import-id
|
||||||
|
|
||||||
:import-batch/status :import-status/completed}
|
:import-batch/status :import-status/completed}
|
||||||
@stats)])))))
|
@stats)])))))
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
[clj-time.coerce :as coerce]
|
[clj-time.coerce :as coerce]
|
||||||
[clojure.string :as str]
|
[clojure.string :as str]
|
||||||
[com.unbounce.dogstatsd.core :as statsd]
|
[com.unbounce.dogstatsd.core :as statsd]
|
||||||
[datomic.client.api :as dc]
|
[datomic.api :as dc]
|
||||||
[digest :as di]
|
[digest :as di]
|
||||||
[unilog.context :as lc]))
|
[unilog.context :as lc]))
|
||||||
|
|
||||||
|
|||||||
@@ -6,23 +6,23 @@
|
|||||||
[auto-ap.time :as time]
|
[auto-ap.time :as time]
|
||||||
[clj-time.coerce :as coerce]
|
[clj-time.coerce :as coerce]
|
||||||
[clojure.tools.logging :as log]
|
[clojure.tools.logging :as log]
|
||||||
[datomic.client.api :as dc]))
|
[datomic.api :as dc]))
|
||||||
|
|
||||||
(defn close-auto-invoices []
|
(defn close-auto-invoices []
|
||||||
(let [invoices-to-close (dc/q {:query {:find ['?e]
|
(let [invoices-to-close (dc/q {:find ['?e]
|
||||||
:in ['$ '?today]
|
:in ['$ '?today]
|
||||||
:where ['[?e :invoice/scheduled-payment ?d]
|
:where ['[?e :invoice/scheduled-payment ?d]
|
||||||
'[?e :invoice/status :invoice-status/unpaid]
|
'[?e :invoice/status :invoice-status/unpaid]
|
||||||
'[(<= ?d ?today)]]}
|
'[(<= ?d ?today)]]}
|
||||||
:args [(dc/db conn) (coerce/to-date (time/local-now))]})]
|
(dc/db conn) (coerce/to-date (time/local-now)))]
|
||||||
(log/info "Closing " (count invoices-to-close) "scheduled invoices")
|
(log/info "Closing " (count invoices-to-close) "scheduled invoices")
|
||||||
(dc/transact conn {:tx-data (some->> invoices-to-close
|
@(dc/transact conn (some->> invoices-to-close
|
||||||
seq
|
seq
|
||||||
|
|
||||||
(mapv (fn [[i]] {:db/id i
|
(mapv (fn [[i]] {:db/id i
|
||||||
:invoice/outstanding-balance 0.0
|
:invoice/outstanding-balance 0.0
|
||||||
:invoice/status :invoice-status/paid}))
|
:invoice/status :invoice-status/paid}))
|
||||||
)})
|
))
|
||||||
(log/info "Closed " (count invoices-to-close) "scheduled invoices")))
|
(log/info "Closed " (count invoices-to-close) "scheduled invoices")))
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
(ns auto-ap.jobs.core
|
(ns auto-ap.jobs.core
|
||||||
(:require [auto-ap.utils :refer [heartbeat]]
|
(:require [auto-ap.utils :refer [heartbeat]]
|
||||||
[mount.core :as mount]
|
[mount.core :as mount]
|
||||||
[auto-ap.datomic :refer [conn client]]
|
[auto-ap.datomic :refer [conn ]]
|
||||||
[clojure.tools.logging :as log]
|
[clojure.tools.logging :as log]
|
||||||
[nrepl.server :refer [start-server]]
|
[nrepl.server :refer [start-server]]
|
||||||
[auto-ap.background.metrics :refer [metrics-setup container-tags container-data logging-context]]
|
[auto-ap.background.metrics :refer [metrics-setup container-tags container-data logging-context]]
|
||||||
@@ -13,7 +13,7 @@
|
|||||||
(lc/with-context {:background-job name}
|
(lc/with-context {:background-job name}
|
||||||
(mu/with-context {:background-job name
|
(mu/with-context {:background-job name
|
||||||
:service name}
|
:service name}
|
||||||
(mount/start (mount/only #{#'conn #'client #'metrics-setup #'container-tags #'logging-context #'container-data }))
|
(mount/start (mount/only #{#'conn #'metrics-setup #'container-tags #'logging-context #'container-data }))
|
||||||
(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))
|
||||||
((heartbeat f name))
|
((heartbeat f name))
|
||||||
(log/info "Stopping " name)
|
(log/info "Stopping " name)
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
[clj-time.periodic :as per]
|
[clj-time.periodic :as per]
|
||||||
[clojure.tools.logging :as log]
|
[clojure.tools.logging :as log]
|
||||||
[config.core :refer [env]]
|
[config.core :refer [env]]
|
||||||
[datomic.client.api :as dc]
|
[datomic.api :as dc]
|
||||||
[unilog.context :as lc]))
|
[unilog.context :as lc]))
|
||||||
|
|
||||||
#_{:clj-kondo/ignore [:clojure-lsp/unused-public-var]}
|
#_{:clj-kondo/ignore [:clojure-lsp/unused-public-var]}
|
||||||
|
|||||||
@@ -13,8 +13,8 @@
|
|||||||
[clojure.string :as str]
|
[clojure.string :as str]
|
||||||
[clojure.xml :as xml]
|
[clojure.xml :as xml]
|
||||||
[clojure.zip :as zip]
|
[clojure.zip :as zip]
|
||||||
[datomic.client.api :as d]
|
[datomic.api :as d]
|
||||||
[iol-ion.tx :refer [propose-invoice random-tempid]])
|
[iol-ion.tx :refer [random-tempid]])
|
||||||
(:import
|
(:import
|
||||||
(java.util UUID)))
|
(java.util UUID)))
|
||||||
|
|
||||||
@@ -249,7 +249,7 @@
|
|||||||
:invoice i)
|
:invoice i)
|
||||||
i))
|
i))
|
||||||
(mapv (fn [i]
|
(mapv (fn [i]
|
||||||
`(propose-invoice ~(assoc i :invoice/source-url invoice-url))))))) (catch Exception e
|
[:propose-invoice (assoc i :invoice/source-url invoice-url)]))))) (catch Exception e
|
||||||
(log/error ::cant-load-file
|
(log/error ::cant-load-file
|
||||||
:key k
|
:key k
|
||||||
:exception e)
|
:exception e)
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
[clojure.string :as str]
|
[clojure.string :as str]
|
||||||
[clojure.tools.logging :as log]
|
[clojure.tools.logging :as log]
|
||||||
[config.core :refer [env]]
|
[config.core :refer [env]]
|
||||||
[datomic.client.api :as dc])
|
[datomic.api :as dc])
|
||||||
(:import
|
(:import
|
||||||
(java.util UUID)))
|
(java.util UUID)))
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
[clojure.set :as set]
|
[clojure.set :as set]
|
||||||
[com.brunobonacci.mulog :as mu]
|
[com.brunobonacci.mulog :as mu]
|
||||||
[config.core :refer [env]]
|
[config.core :refer [env]]
|
||||||
[datomic.client.api :as dc]
|
[datomic.api :as dc]
|
||||||
[lambdaisland.edn-lines :as ednl]
|
[lambdaisland.edn-lines :as ednl]
|
||||||
[manifold.deferred :as de]
|
[manifold.deferred :as de]
|
||||||
[manifold.executor :as ex]
|
[manifold.executor :as ex]
|
||||||
@@ -97,20 +97,20 @@
|
|||||||
(let [schema (edn/read-string (slurp (pull-file backup-id "schema.edn")))
|
(let [schema (edn/read-string (slurp (pull-file backup-id "schema.edn")))
|
||||||
full-dependencies (edn/read-string (slurp (pull-file backup-id "full-dependencies.edn")))
|
full-dependencies (edn/read-string (slurp (pull-file backup-id "full-dependencies.edn")))
|
||||||
entity-dependencies (edn/read-string (slurp (pull-file backup-id "entity-dependencies.edn")))]
|
entity-dependencies (edn/read-string (slurp (pull-file backup-id "entity-dependencies.edn")))]
|
||||||
(dc/transact connection {:tx-data [{:db/ident :entity/migration-key
|
@(dc/transact connection [{:db/ident :entity/migration-key
|
||||||
:db/unique :db.unique/identity
|
:db/unique :db.unique/identity
|
||||||
:db/cardinality :db.cardinality/one
|
:db/cardinality :db.cardinality/one
|
||||||
:db/valueType :db.type/long}]})
|
:db/valueType :db.type/long}])
|
||||||
(dc/transact connection {:tx-data (map
|
@(dc/transact connection (map
|
||||||
(fn [s]
|
(fn [s]
|
||||||
(set/rename-keys s {:db/id :entity/migration-key}))
|
(set/rename-keys s {:db/id :entity/migration-key}))
|
||||||
schema)})
|
schema))
|
||||||
|
|
||||||
;; TEMP - this has been fixed in current export (ezcater-olaciotn)
|
;; TEMP - this has been fixed in current export (ezcater-olaciotn)
|
||||||
(dc/transact connection {:tx-data [{:entity/migration-key 17592257603901 :vendor/name "unknown"}
|
@(dc/transact connection [{:entity/migration-key 17592257603901 :vendor/name "unknown"}
|
||||||
{:entity/migration-key 17592232621701}
|
{:entity/migration-key 17592232621701}
|
||||||
{:entity/migration-key 17592263907739}
|
{:entity/migration-key 17592263907739}
|
||||||
{:entity/migration-key 17592271516922}]})
|
{:entity/migration-key 17592271516922}])
|
||||||
|
|
||||||
|
|
||||||
(doseq [entity (cond->> (order-of-insert entity-dependencies)
|
(doseq [entity (cond->> (order-of-insert entity-dependencies)
|
||||||
|
|||||||
@@ -6,7 +6,6 @@
|
|||||||
[auto-ap.datomic :refer [audit-transact]]
|
[auto-ap.datomic :refer [audit-transact]]
|
||||||
[auto-ap.datomic.clients :as d-clients]
|
[auto-ap.datomic.clients :as d-clients]
|
||||||
[auto-ap.datomic.invoices :refer [code-invoice]]
|
[auto-ap.datomic.invoices :refer [code-invoice]]
|
||||||
[iol-ion.tx :refer [propose-invoice]]
|
|
||||||
[auto-ap.parse :as parse]
|
[auto-ap.parse :as parse]
|
||||||
[auto-ap.time :as t]
|
[auto-ap.time :as t]
|
||||||
[clj-time.coerce :as coerce]
|
[clj-time.coerce :as coerce]
|
||||||
@@ -16,7 +15,7 @@
|
|||||||
[clojure.tools.logging :as log]
|
[clojure.tools.logging :as log]
|
||||||
[com.unbounce.dogstatsd.core :as statsd]
|
[com.unbounce.dogstatsd.core :as statsd]
|
||||||
[config.core :refer [env]]
|
[config.core :refer [env]]
|
||||||
[datomic.client.api :as dc]
|
[datomic.api :as dc]
|
||||||
[auto-ap.datomic.vendors :as d-vendors])
|
[auto-ap.datomic.vendors :as d-vendors])
|
||||||
(:import
|
(:import
|
||||||
(java.util UUID)))
|
(java.util UUID)))
|
||||||
@@ -134,11 +133,11 @@
|
|||||||
:destination-bucket-name (:data-bucket env)
|
:destination-bucket-name (:data-bucket env)
|
||||||
:source-key k
|
:source-key k
|
||||||
:destination-key invoice-key})
|
:destination-key invoice-key})
|
||||||
[`(propose-invoice
|
[[:propose-invoice
|
||||||
~(-> k
|
(-> k
|
||||||
read-sysco-csv
|
read-sysco-csv
|
||||||
(extract-invoice-details sysco-vendor)
|
(extract-invoice-details sysco-vendor)
|
||||||
(assoc :invoice/source-url invoice-url)))])
|
(assoc :invoice/source-url invoice-url))]])
|
||||||
(catch Exception e
|
(catch Exception e
|
||||||
(log/error (str "Cannot load file " k) e)
|
(log/error (str "Cannot load file " k) e)
|
||||||
(log/info
|
(log/info
|
||||||
|
|||||||
@@ -3,10 +3,10 @@
|
|||||||
(:require
|
(:require
|
||||||
[auto-ap.datomic :refer [conn]]
|
[auto-ap.datomic :refer [conn]]
|
||||||
[auto-ap.jobs.core :refer [execute]]
|
[auto-ap.jobs.core :refer [execute]]
|
||||||
[datomic.client.api :as dc]))
|
[datomic.api :as dc]))
|
||||||
|
|
||||||
(defn refresh-vendor-usages []
|
(defn refresh-vendor-usages []
|
||||||
(dc/transact conn {:tx-data (->> (dc/q '[:find ?v ?c (count ?e)
|
@(dc/transact conn (->> (dc/q '[:find ?v ?c (count ?e)
|
||||||
:in $
|
:in $
|
||||||
:where
|
:where
|
||||||
[?v :vendor/name]
|
[?v :vendor/name]
|
||||||
@@ -25,7 +25,7 @@
|
|||||||
#:vendor-usage {:vendor v
|
#:vendor-usage {:vendor v
|
||||||
:client c
|
:client c
|
||||||
:key (str v "-" c)
|
:key (str v "-" c)
|
||||||
:count cnt})))}))
|
:count cnt})))))
|
||||||
|
|
||||||
(defn -main [& _]
|
(defn -main [& _]
|
||||||
(execute "vendor-usages" refresh-vendor-usages))
|
(execute "vendor-usages" refresh-vendor-usages))
|
||||||
|
|||||||
@@ -6,8 +6,7 @@
|
|||||||
[clj-time.core :as t]
|
[clj-time.core :as t]
|
||||||
[com.brunobonacci.mulog :as mu]
|
[com.brunobonacci.mulog :as mu]
|
||||||
[com.unbounce.dogstatsd.core :as statsd]
|
[com.unbounce.dogstatsd.core :as statsd]
|
||||||
[datomic.client.api :as dc]
|
[datomic.api :as dc]
|
||||||
[iol-ion.tx :refer [upsert-invoice upsert-ledger upsert-transaction]]
|
|
||||||
[manifold.deferred :as de]
|
[manifold.deferred :as de]
|
||||||
[manifold.stream :as s]
|
[manifold.stream :as s]
|
||||||
[mount.core :as mount]
|
[mount.core :as mount]
|
||||||
@@ -18,7 +17,7 @@
|
|||||||
(t/plus (t/months -6))
|
(t/plus (t/months -6))
|
||||||
(c/to-date))))
|
(c/to-date))))
|
||||||
([start-date]
|
([start-date]
|
||||||
(let [txes-missing-ledger-entries (->> (dc/q {:query {:find ['?t ]
|
(let [txes-missing-ledger-entries (->> (dc/q {:find ['?t ]
|
||||||
:in ['$ '?sd]
|
:in ['$ '?sd]
|
||||||
:where [
|
:where [
|
||||||
'[?t :transaction/date ?d]
|
'[?t :transaction/date ?d]
|
||||||
@@ -28,13 +27,13 @@
|
|||||||
'(not [?t :transaction/approval-status :transaction-approval-status/excluded])
|
'(not [?t :transaction/approval-status :transaction-approval-status/excluded])
|
||||||
'(not [?t :transaction/approval-status :transaction-approval-status/suppressed])
|
'(not [?t :transaction/approval-status :transaction-approval-status/suppressed])
|
||||||
]}
|
]}
|
||||||
:args [(dc/db conn) start-date]})
|
(dc/db conn) start-date)
|
||||||
(map first)
|
(map first)
|
||||||
(mapv (fn [t]
|
(mapv (fn [t]
|
||||||
`(upsert-transaction ~{:db/id t}))))
|
[:upsert-transaction {:db/id t}])))
|
||||||
|
|
||||||
|
|
||||||
invoices-missing-ledger-entries (->> (dc/q {:query {:find ['?t ]
|
invoices-missing-ledger-entries (->> (dc/q {:find ['?t ]
|
||||||
:in ['$ '?sd]
|
:in ['$ '?sd]
|
||||||
:where ['[?t :invoice/date ?d]
|
:where ['[?t :invoice/date ?d]
|
||||||
'[(>= ?d ?sd)]
|
'[(>= ?d ?sd)]
|
||||||
@@ -45,30 +44,30 @@
|
|||||||
'(not [?t :invoice/import-status :import-status/pending])
|
'(not [?t :invoice/import-status :import-status/pending])
|
||||||
'(not [?t :invoice/exclude-from-ledger true])
|
'(not [?t :invoice/exclude-from-ledger true])
|
||||||
]}
|
]}
|
||||||
:args [(dc/db conn) start-date]})
|
(dc/db conn) start-date)
|
||||||
(map first)
|
(map first)
|
||||||
(mapv (fn [i]
|
(mapv (fn [i]
|
||||||
`(upsert-invoice ~{:db/id i}))))
|
[:upsert-invoice {:db/id i}])))
|
||||||
repairs (vec (concat txes-missing-ledger-entries invoices-missing-ledger-entries))]
|
repairs (vec (concat txes-missing-ledger-entries invoices-missing-ledger-entries))]
|
||||||
(when (seq repairs)
|
(when (seq repairs)
|
||||||
(mu/log ::ledger-repairs-needed
|
(mu/log ::ledger-repairs-needed
|
||||||
:sample (take 3 repairs)
|
:sample (take 3 repairs)
|
||||||
:transaction-count (count txes-missing-ledger-entries)
|
:transaction-count (count txes-missing-ledger-entries)
|
||||||
:invoice-count (count invoices-missing-ledger-entries))
|
:invoice-count (count invoices-missing-ledger-entries))
|
||||||
(dc/transact conn {:tx-data (map (fn [repair]
|
@(dc/transact conn (map (fn [repair]
|
||||||
`(upsert-ledger ~repair))
|
[:upsert-ledger repair])
|
||||||
repairs) })))))
|
repairs))))))
|
||||||
|
|
||||||
|
|
||||||
(defn touch-transaction [e]
|
(defn touch-transaction [e]
|
||||||
(dc/transact conn {:tx-data [{:db/id "datomic.tx"
|
@(dc/transact conn [{:db/id "datomic.tx"
|
||||||
:db/doc "touching transaction to update ledger"}
|
:db/doc "touching transaction to update ledger"}
|
||||||
`(upsert-transaction ~{:db/id e})]}))
|
[:upsert-transaction {:db/id e}]]))
|
||||||
|
|
||||||
(defn touch-invoice [e]
|
(defn touch-invoice [e]
|
||||||
(dc/transact conn {:tx-data [{:db/id "datomic.tx"
|
@(dc/transact conn [{:db/id "datomic.tx"
|
||||||
:db/doc "touching invoice to update ledger"}
|
:db/doc "touching invoice to update ledger"}
|
||||||
`(upsert-invoice ~{:db/id e})]}))
|
[:upsert-invoice {:db/id e}]]))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -297,19 +296,19 @@
|
|||||||
|
|
||||||
|
|
||||||
(defn build-account-lookup [client-id]
|
(defn build-account-lookup [client-id]
|
||||||
(let [accounts (by :db/id (map first (dc/q {:query {:find ['(pull ?e [:db/id :account/name
|
(let [accounts (by :db/id (map first (dc/q {:find ['(pull ?e [:db/id :account/name
|
||||||
:account/numeric-code
|
:account/numeric-code
|
||||||
{:account/type [:db/ident]
|
{:account/type [:db/ident]
|
||||||
:account/client-overrides [:account-client-override/client :account-client-override/name]}
|
:account/client-overrides [:account-client-override/client :account-client-override/name]}
|
||||||
])]
|
])]
|
||||||
:in ['$]
|
:in ['$]
|
||||||
:where ['[?e :account/name]]}
|
:where ['[?e :account/name]]}
|
||||||
:args [(dc/db conn )]})))
|
(dc/db conn ))))
|
||||||
|
|
||||||
bank-accounts (by :db/id (map first (dc/q {:query {:find ['(pull ?e [:db/id :bank-account/name :bank-account/numeric-code {:bank-account/type [:db/ident]}])]
|
bank-accounts (by :db/id (map first (dc/q {:find ['(pull ?e [:db/id :bank-account/name :bank-account/numeric-code {:bank-account/type [:db/ident]}])]
|
||||||
:in ['$]
|
:in ['$]
|
||||||
:where ['[?e :bank-account/name]]}
|
:where ['[?e :bank-account/name]]}
|
||||||
:args [(dc/db conn)]})))
|
(dc/db conn))))
|
||||||
overrides-by-client (->> accounts
|
overrides-by-client (->> accounts
|
||||||
vals
|
vals
|
||||||
(mapcat (fn [a]
|
(mapcat (fn [a]
|
||||||
@@ -344,10 +343,10 @@
|
|||||||
:client-count (count clients)}
|
:client-count (count clients)}
|
||||||
(mu/log ::reseting-index)
|
(mu/log ::reseting-index)
|
||||||
(let [so-far (atom 0)]
|
(let [so-far (atom 0)]
|
||||||
@(->> (dc/qseq '[:find (pull ?je [:journal-entry/date :journal-entry/client {:journal-entry/line-items [:journal-entry-line/account :journal-entry-line/location :db/id]}])
|
@(->> (dc/qseq {:query '[:find (pull ?je [:journal-entry/date :journal-entry/client {:journal-entry/line-items [:journal-entry-line/account :journal-entry-line/location :db/id]}])
|
||||||
:in $ ?c
|
:in $ ?c
|
||||||
:where [?je :journal-entry/client ?c]]
|
:where [?je :journal-entry/client ?c]]
|
||||||
(dc/db conn)
|
:args [(dc/db conn)]}
|
||||||
client)
|
client)
|
||||||
(map first)
|
(map first)
|
||||||
(mapcat (fn [je]
|
(mapcat (fn [je]
|
||||||
@@ -402,7 +401,7 @@
|
|||||||
|
|
||||||
(defn accounts-needing-rebuild [ db client]
|
(defn accounts-needing-rebuild [ db client]
|
||||||
(let [client (pull-id db client)]
|
(let [client (pull-id db client)]
|
||||||
(->> (dc/qseq '[:find ?c ?a ?l (min ?d)
|
(->> (dc/qseq {:query '[:find ?c ?a ?l (min ?d)
|
||||||
:in $ ?c
|
:in $ ?c
|
||||||
:where
|
:where
|
||||||
[?jel :journal-entry-line/dirty true]
|
[?jel :journal-entry-line/dirty true]
|
||||||
@@ -411,8 +410,7 @@
|
|||||||
[?je :journal-entry/line-items ?jel]
|
[?je :journal-entry/line-items ?jel]
|
||||||
[?je :journal-entry/client ?c]
|
[?je :journal-entry/client ?c]
|
||||||
[?je :journal-entry/date ?d]]
|
[?je :journal-entry/date ?d]]
|
||||||
db
|
:args [db client]})
|
||||||
client)
|
|
||||||
(map (fn [[client account location starting-at ]]
|
(map (fn [[client account location starting-at ]]
|
||||||
{:client client
|
{:client client
|
||||||
:account account
|
:account account
|
||||||
@@ -421,7 +419,7 @@
|
|||||||
|
|
||||||
(defn all-accounts-needing-rebuild [ db client]
|
(defn all-accounts-needing-rebuild [ db client]
|
||||||
(let [client (pull-id db client)]
|
(let [client (pull-id db client)]
|
||||||
(->> (dc/qseq '[:find ?c ?a ?l (min ?d)
|
(->> (dc/qseq {:query '[:find ?c ?a ?l (min ?d)
|
||||||
:in $ ?c
|
:in $ ?c
|
||||||
:where
|
:where
|
||||||
[?je :journal-entry/client ?c]
|
[?je :journal-entry/client ?c]
|
||||||
@@ -429,8 +427,7 @@
|
|||||||
[?jel :journal-entry-line/account ?a]
|
[?jel :journal-entry-line/account ?a]
|
||||||
[?jel :journal-entry-line/location ?l]
|
[?jel :journal-entry-line/location ?l]
|
||||||
[?je :journal-entry/date ?d]]
|
[?je :journal-entry/date ?d]]
|
||||||
db
|
:args [db client]})
|
||||||
client)
|
|
||||||
(map (fn [[client account location starting-at ]]
|
(map (fn [[client account location starting-at ]]
|
||||||
{:client client
|
{:client client
|
||||||
:account account
|
:account account
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
[clojure.string :as str]
|
[clojure.string :as str]
|
||||||
[clojure.tools.logging :as log]
|
[clojure.tools.logging :as log]
|
||||||
[config.core :refer [env]]
|
[config.core :refer [env]]
|
||||||
[datomic.client.api :as dc])
|
[datomic.api :as dc])
|
||||||
(:import
|
(:import
|
||||||
(java.io ByteArrayOutputStream)
|
(java.io ByteArrayOutputStream)
|
||||||
(java.text DecimalFormat)
|
(java.text DecimalFormat)
|
||||||
@@ -342,13 +342,13 @@
|
|||||||
:input-stream (io/make-input-stream pdf-data {})
|
:input-stream (io/make-input-stream pdf-data {})
|
||||||
:metadata {:content-length (count pdf-data)
|
:metadata {:content-length (count pdf-data)
|
||||||
:content-type "application/pdf"})
|
:content-type "application/pdf"})
|
||||||
(dc/transact conn
|
@(dc/transact conn
|
||||||
{:tx-data [{:report/name name
|
[{:report/name name
|
||||||
:report/client (:client_ids args)
|
:report/client (:client_ids args)
|
||||||
:report/key key
|
:report/key key
|
||||||
:report/url url
|
:report/url url
|
||||||
:report/creator (:user user)
|
:report/creator (:user user)
|
||||||
:report/created (java.util.Date.)}]})
|
:report/created (java.util.Date.)}])
|
||||||
{:report/name name
|
{:report/name name
|
||||||
:report/url url }))
|
:report/url url }))
|
||||||
|
|
||||||
@@ -363,13 +363,13 @@
|
|||||||
:input-stream (io/make-input-stream pdf-data {})
|
:input-stream (io/make-input-stream pdf-data {})
|
||||||
:metadata {:content-length (count pdf-data)
|
:metadata {:content-length (count pdf-data)
|
||||||
:content-type "application/pdf"})
|
:content-type "application/pdf"})
|
||||||
(dc/transact conn
|
@(dc/transact conn
|
||||||
{:tx-data [{:report/name name
|
[{:report/name name
|
||||||
:report/client (:client_ids args)
|
:report/client (:client_ids args)
|
||||||
:report/key key
|
:report/key key
|
||||||
:report/url url
|
:report/url url
|
||||||
:report/creator (:user user)
|
:report/creator (:user user)
|
||||||
:report/created (java.util.Date.)}]})
|
:report/created (java.util.Date.)}])
|
||||||
{:report/name name
|
{:report/name name
|
||||||
:report/url url }))
|
:report/url url }))
|
||||||
|
|
||||||
@@ -384,14 +384,13 @@
|
|||||||
:input-stream (io/make-input-stream pdf-data {})
|
:input-stream (io/make-input-stream pdf-data {})
|
||||||
:metadata {:content-length (count pdf-data)
|
:metadata {:content-length (count pdf-data)
|
||||||
:content-type "application/pdf"})
|
:content-type "application/pdf"})
|
||||||
(dc/transact conn
|
@(dc/transact conn
|
||||||
{:tx-data
|
|
||||||
[{:report/name name
|
[{:report/name name
|
||||||
:report/client [(:client_id args)]
|
:report/client [(:client_id args)]
|
||||||
:report/key key
|
:report/key key
|
||||||
:report/url url
|
:report/url url
|
||||||
:report/creator (:user user)
|
:report/creator (:user user)
|
||||||
:report/created (java.util.Date.)}]})
|
:report/created (java.util.Date.)}])
|
||||||
{:report/name name
|
{:report/name name
|
||||||
:report/url url }))
|
:report/url url }))
|
||||||
|
|
||||||
@@ -406,13 +405,12 @@
|
|||||||
:input-stream (io/make-input-stream pdf-data {})
|
:input-stream (io/make-input-stream pdf-data {})
|
||||||
:metadata {:content-length (count pdf-data)
|
:metadata {:content-length (count pdf-data)
|
||||||
:content-type "application/pdf"})
|
:content-type "application/pdf"})
|
||||||
(dc/transact conn
|
@(dc/transact conn
|
||||||
{:tx-data
|
|
||||||
[{:report/name name
|
[{:report/name name
|
||||||
:report/client (:client_ids args)
|
:report/client (:client_ids args)
|
||||||
:report/key key
|
:report/key key
|
||||||
:report/url url
|
:report/url url
|
||||||
:report/creator (:user user)
|
:report/creator (:user user)
|
||||||
:report/created (java.util.Date.)}]})
|
:report/created (java.util.Date.)}])
|
||||||
{:report/name name
|
{:report/name name
|
||||||
:report/url url }))
|
:report/url url }))
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
[clojure.tools.logging :as log]
|
[clojure.tools.logging :as log]
|
||||||
[com.unbounce.dogstatsd.core :as statsd]
|
[com.unbounce.dogstatsd.core :as statsd]
|
||||||
[config.core :refer [env]]
|
[config.core :refer [env]]
|
||||||
[datomic.client.api :as dc]
|
[datomic.api :as dc]
|
||||||
[ring.middleware.json :refer [wrap-json-response]]
|
[ring.middleware.json :refer [wrap-json-response]]
|
||||||
[venia.core :as venia]))
|
[venia.core :as venia]))
|
||||||
|
|
||||||
@@ -35,7 +35,7 @@
|
|||||||
identity (jwt/unsign (get query-params "key") (:jwt-secret env) {:alg :hs512})]
|
identity (jwt/unsign (get query-params "key") (:jwt-secret env) {:alg :hs512})]
|
||||||
(assert-can-see-client identity client-id)
|
(assert-can-see-client identity client-id)
|
||||||
(into (list)
|
(into (list)
|
||||||
(dc/q {:query {:find '[?d4 (sum ?total) (sum ?tax) (sum ?tip) (sum ?service-charge)]
|
(dc/q {:find '[?d4 (sum ?total) (sum ?tax) (sum ?tip) (sum ?service-charge)]
|
||||||
:in '[$ ?c]
|
:in '[$ ?c]
|
||||||
:where '[[?s :sales-order/client ?c]
|
:where '[[?s :sales-order/client ?c]
|
||||||
[?s :sales-order/date ?d]
|
[?s :sales-order/date ?d]
|
||||||
@@ -46,7 +46,7 @@
|
|||||||
[(clj-time.coerce/to-date-time ?d) ?d2]
|
[(clj-time.coerce/to-date-time ?d) ?d2]
|
||||||
[(auto-ap.time/localize ?d2) ?d3]
|
[(auto-ap.time/localize ?d2) ?d3]
|
||||||
[(auto-ap.time/unparse ?d3 auto-ap.time/normal-date) ?d4]]}
|
[(auto-ap.time/unparse ?d3 auto-ap.time/normal-date) ?d4]]}
|
||||||
:args [(dc/db conn) client-id]}))))
|
(dc/db conn) client-id))))
|
||||||
|
|
||||||
(defn client-tag [params]
|
(defn client-tag [params]
|
||||||
(when-let [code (or (params "client-code")
|
(when-let [code (or (params "client-code")
|
||||||
@@ -369,10 +369,10 @@
|
|||||||
"export:transactions2"}}]
|
"export:transactions2"}}]
|
||||||
{:body (let [db (dc/db conn)]
|
{:body (let [db (dc/db conn)]
|
||||||
(->>
|
(->>
|
||||||
(dc/q {:query {:find ['?e]
|
(dc/q {:find ['?e]
|
||||||
:in ['$ '?client-code]
|
:in ['$ '?client-code]
|
||||||
:where ['[?e :transaction/client ?client-code]]}
|
:where ['[?e :transaction/client ?client-code]]}
|
||||||
:args [db [:client/code (query-params "client-code")]]})
|
db [:client/code (query-params "client-code")])
|
||||||
(map first)
|
(map first)
|
||||||
;; TODO
|
;; TODO
|
||||||
#_(map (fn [e]
|
#_(map (fn [e]
|
||||||
|
|||||||
@@ -18,9 +18,9 @@
|
|||||||
[clojure.string :as str]
|
[clojure.string :as str]
|
||||||
[clojure.tools.logging :as log]
|
[clojure.tools.logging :as log]
|
||||||
[config.core :refer [env]]
|
[config.core :refer [env]]
|
||||||
[datomic.client.api :as dc]
|
[datomic.api :as dc]
|
||||||
[digest]
|
[digest]
|
||||||
[iol-ion.tx :refer [propose-invoice random-tempid]]
|
[iol-ion.tx :refer [random-tempid]]
|
||||||
[ring.middleware.json :refer [wrap-json-response]]
|
[ring.middleware.json :refer [wrap-json-response]]
|
||||||
[unilog.context :as lc])
|
[unilog.context :as lc])
|
||||||
(:import
|
(:import
|
||||||
@@ -114,10 +114,10 @@
|
|||||||
{:vendor-code vendor-code})))
|
{:vendor-code vendor-code})))
|
||||||
(let [vendor-id (or forced-vendor
|
(let [vendor-id (or forced-vendor
|
||||||
(->> (dc/q
|
(->> (dc/q
|
||||||
{:query {:find ['?vendor]
|
{:find ['?vendor]
|
||||||
:in ['$ '?vendor-name]
|
:in ['$ '?vendor-name]
|
||||||
:where ['[?vendor :vendor/name ?vendor-name]]}
|
:where ['[?vendor :vendor/name ?vendor-name]]}
|
||||||
:args [(dc/db conn) vendor-code]})
|
(dc/db conn) vendor-code)
|
||||||
first
|
first
|
||||||
first))]
|
first))]
|
||||||
(when-not vendor-id
|
(when-not vendor-id
|
||||||
@@ -125,9 +125,9 @@
|
|||||||
{:vendor-code vendor-code})))
|
{:vendor-code vendor-code})))
|
||||||
|
|
||||||
(if-let [matching-vendor (->> (dc/q
|
(if-let [matching-vendor (->> (dc/q
|
||||||
{:query {:find [(list 'pull '?vendor-id d-vendors/default-read)]
|
{:find [(list 'pull '?vendor-id d-vendors/default-read)]
|
||||||
:in ['$ '?vendor-id]}
|
:in ['$ '?vendor-id]}
|
||||||
:args [(dc/db conn) vendor-id]})
|
(dc/db conn) vendor-id)
|
||||||
first
|
first
|
||||||
first)]
|
first)]
|
||||||
matching-vendor
|
matching-vendor
|
||||||
@@ -231,8 +231,8 @@
|
|||||||
:transaction-account/location "A"
|
:transaction-account/location "A"
|
||||||
:transaction-account/amount (Math/abs (:invoice/total invoice))}]}))
|
:transaction-account/amount (Math/abs (:invoice/total invoice))}]}))
|
||||||
]
|
]
|
||||||
[`(propose-invoice ~(d-invoices/code-invoice (validate-invoice (remove-nils invoice)
|
[[:propose-invoice (d-invoices/code-invoice (validate-invoice (remove-nils invoice)
|
||||||
user)))
|
user))]
|
||||||
(some-> payment remove-nils)
|
(some-> payment remove-nils)
|
||||||
transaction])))
|
transaction])))
|
||||||
(filter identity)))
|
(filter identity)))
|
||||||
@@ -252,7 +252,7 @@
|
|||||||
(map #(validate-invoice % user))
|
(map #(validate-invoice % user))
|
||||||
admin-only-if-multiple-clients
|
admin-only-if-multiple-clients
|
||||||
(mapv d-invoices/code-invoice)
|
(mapv d-invoices/code-invoice)
|
||||||
(mapv (fn [i] `(propose-invoice ~i))))]
|
(mapv (fn [i] [:propose-invoice i])))]
|
||||||
|
|
||||||
(log/info "creating invoice" potential-invoices)
|
(log/info "creating invoice" potential-invoices)
|
||||||
(let [tx (audit-transact potential-invoices user)]
|
(let [tx (audit-transact potential-invoices user)]
|
||||||
@@ -288,21 +288,23 @@
|
|||||||
|
|
||||||
(defn import-account-overrides [customer filename]
|
(defn import-account-overrides [customer filename]
|
||||||
(let [[_ & rows] (-> filename (io/reader) csv/read-csv)
|
(let [[_ & rows] (-> filename (io/reader) csv/read-csv)
|
||||||
[client-id] (first (dc/q (-> {:query {:find ['?e]
|
[client-id] (first (dc/q (-> {:find ['?e]
|
||||||
:in ['$ '?z]
|
:in ['$ '?z]
|
||||||
:where [['?e :client/code '?z]]}
|
:where [['?e :client/code '?z]]}
|
||||||
:args [(dc/db conn) customer]})))
|
(dc/db conn)
|
||||||
code->existing-account (by :account/numeric-code (map first (dc/q {:query {:find ['(pull ?e [:account/numeric-code
|
customer)))
|
||||||
|
code->existing-account (by :account/numeric-code (map first (dc/q {:find ['(pull ?e [:account/numeric-code
|
||||||
{:account/applicability [:db/ident]}
|
{:account/applicability [:db/ident]}
|
||||||
:db/id])]
|
:db/id])]
|
||||||
:in ['$]
|
:in ['$]
|
||||||
:where ['[?e :account/name]]}
|
:where ['[?e :account/name]]}
|
||||||
:args [(dc/db conn)]})))
|
(dc/db conn))))
|
||||||
|
|
||||||
existing-account-overrides (dc/q (-> {:query {:find ['?e]
|
existing-account-overrides (dc/q (-> {:find ['?e]
|
||||||
:in ['$ '?client-id]
|
:in ['$ '?client-id]
|
||||||
:where [['?e :account-client-override/client '?client-id]]}
|
:where [['?e :account-client-override/client '?client-id]]}
|
||||||
:args [(dc/db conn) client-id]}))
|
(dc/db conn)
|
||||||
|
client-id))
|
||||||
rows (transduce (comp
|
rows (transduce (comp
|
||||||
(map (fn [[_ account account-name override-name _ type]]
|
(map (fn [[_ account account-name override-name _ type]]
|
||||||
[account account-name override-name type]))
|
[account account-name override-name type]))
|
||||||
@@ -357,7 +359,7 @@
|
|||||||
existing-account-overrides)
|
existing-account-overrides)
|
||||||
rows)]
|
rows)]
|
||||||
|
|
||||||
(dc/transact conn {:tx-data txes})
|
@(dc/transact conn txes)
|
||||||
txes))
|
txes))
|
||||||
|
|
||||||
(defn import-transactions-cleared-against [file]
|
(defn import-transactions-cleared-against [file]
|
||||||
|
|||||||
@@ -10,8 +10,8 @@
|
|||||||
[clojure.tools.logging :as log]
|
[clojure.tools.logging :as log]
|
||||||
[com.unbounce.dogstatsd.core :as statsd]
|
[com.unbounce.dogstatsd.core :as statsd]
|
||||||
[config.core :refer [env]]
|
[config.core :refer [env]]
|
||||||
[datomic.client.api :as dc]
|
[datomic.api :as dc]
|
||||||
[iol-ion.tx :refer [random-tempid upsert-entity]]
|
[iol-ion.tx :refer [random-tempid]]
|
||||||
[ring.middleware.json :refer [wrap-json-response]]
|
[ring.middleware.json :refer [wrap-json-response]]
|
||||||
[ring.util.request :refer [body-string]]
|
[ring.util.request :refer [body-string]]
|
||||||
[unilog.context :as lc])
|
[unilog.context :as lc])
|
||||||
@@ -45,12 +45,12 @@
|
|||||||
(or (pull-attr (dc/db conn) :saved-query/guid [:saved-query/lookup-key lookup-key])
|
(or (pull-attr (dc/db conn) :saved-query/guid [:saved-query/lookup-key lookup-key])
|
||||||
guid)
|
guid)
|
||||||
guid)]
|
guid)]
|
||||||
(dc/transact conn {:tx-data [`(upsert-entity ~{:db/id (or id (random-tempid))
|
@(dc/transact conn [[:upsert-entity {:db/id (or id (random-tempid))
|
||||||
:saved-query/guid guid
|
:saved-query/guid guid
|
||||||
:saved-query/description note
|
:saved-query/description note
|
||||||
:saved-query/key (str "queries/" guid)
|
:saved-query/key (str "queries/" guid)
|
||||||
:saved-query/client client
|
:saved-query/client client
|
||||||
:saved-query/lookup-key lookup-key})]})
|
:saved-query/lookup-key lookup-key}]])
|
||||||
(s3/put-object :bucket-name (:data-bucket env)
|
(s3/put-object :bucket-name (:data-bucket env)
|
||||||
:key (str "queries/" guid)
|
:key (str "queries/" guid)
|
||||||
:input-stream (io/make-input-stream (.getBytes body) {})
|
:input-stream (io/make-input-stream (.getBytes body) {})
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
[auto-ap.yodlee.core2 :as yodlee]
|
[auto-ap.yodlee.core2 :as yodlee]
|
||||||
[clojure.tools.logging :as log]
|
[clojure.tools.logging :as log]
|
||||||
[config.core :refer [env]]
|
[config.core :refer [env]]
|
||||||
[datomic.client.api :as dc]))
|
[datomic.api :as dc]))
|
||||||
|
|
||||||
(defn fastlink [{:keys [query-params identity]}]
|
(defn fastlink [{:keys [query-params identity]}]
|
||||||
(assert-can-see-client identity (pull-attr (dc/db conn) :db/id [:client/code (get query-params "client")]))
|
(assert-can-see-client identity (pull-attr (dc/db conn) :db/id [:client/code (get query-params "client")]))
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
[clojure.set :as set]
|
[clojure.set :as set]
|
||||||
[clojure.string :as str]
|
[clojure.string :as str]
|
||||||
[clojure.tools.logging :as log]
|
[clojure.tools.logging :as log]
|
||||||
[datomic.client.api :as dc]
|
[datomic.api :as dc]
|
||||||
[slingshot.slingshot :refer [try+]]
|
[slingshot.slingshot :refer [try+]]
|
||||||
[unilog.context :as lc]))
|
[unilog.context :as lc]))
|
||||||
|
|
||||||
@@ -395,11 +395,11 @@
|
|||||||
(upsert client square-location (time/plus (time/now) (time/days -3)) (time/now))))
|
(upsert client square-location (time/plus (time/now) (time/days -3)) (time/now))))
|
||||||
([client location start end]
|
([client location start end]
|
||||||
(lc/with-context {:source "Square loading"}
|
(lc/with-context {:source "Square loading"}
|
||||||
(let [existing (->> (dc/q {:query {:find ['?external-id]
|
(let [existing (->> (dc/q {:find ['?external-id]
|
||||||
:in ['$ '?client]
|
:in ['$ '?client]
|
||||||
:where ['[?o :sales-order/client ?client]
|
:where ['[?o :sales-order/client ?client]
|
||||||
'[?o :sales-order/external-id ?external-id]]}
|
'[?o :sales-order/external-id ?external-id]]}
|
||||||
:args [(dc/db conn) (:db/id client)]})
|
(dc/db conn) (:db/id client))
|
||||||
(map first)
|
(map first)
|
||||||
set)
|
set)
|
||||||
_ (log/info (count existing) "Sales orders already exist")
|
_ (log/info (count existing) "Sales orders already exist")
|
||||||
@@ -407,7 +407,7 @@
|
|||||||
(daily-results client location start end))]
|
(daily-results client location start end))]
|
||||||
(doseq [x (partition-all 20 to-create)]
|
(doseq [x (partition-all 20 to-create)]
|
||||||
(log/info "Loading " (count x))
|
(log/info "Loading " (count x))
|
||||||
(dc/transact conn {:tx-data x}))))))
|
@(dc/transact conn x))))))
|
||||||
|
|
||||||
(defn upsert-settlements
|
(defn upsert-settlements
|
||||||
([client]
|
([client]
|
||||||
@@ -419,7 +419,7 @@
|
|||||||
:client (:client/code client)}
|
:client (:client/code client)}
|
||||||
(doseq [x (partition-all 20 (daily-settlements client location))]
|
(doseq [x (partition-all 20 (daily-settlements client location))]
|
||||||
(log/info "Loading expected deposit" (count x))
|
(log/info "Loading expected deposit" (count x))
|
||||||
(dc/transact conn {:tx-data x}))
|
@(dc/transact conn x))
|
||||||
(log/info "Done loading settlements"))))
|
(log/info "Done loading settlements"))))
|
||||||
|
|
||||||
(defn upsert-refunds
|
(defn upsert-refunds
|
||||||
@@ -433,7 +433,7 @@
|
|||||||
:location (:square-location/client-location client)}
|
:location (:square-location/client-location client)}
|
||||||
(doseq [x (partition-all 20 (refunds client location))]
|
(doseq [x (partition-all 20 (refunds client location))]
|
||||||
(log/info "Loading refund" (count x))
|
(log/info "Loading refund" (count x))
|
||||||
(dc/transact conn {:tx-data x}))
|
@(dc/transact conn x))
|
||||||
(log/info "Done loading refunds"))))
|
(log/info "Done loading refunds"))))
|
||||||
|
|
||||||
(def square-read [:db/id
|
(def square-read [:db/id
|
||||||
@@ -474,29 +474,29 @@
|
|||||||
[(:square-location/square-id sl)
|
[(:square-location/square-id sl)
|
||||||
(:db/id sl)])
|
(:db/id sl)])
|
||||||
(:client/square-locations client)))]
|
(:client/square-locations client)))]
|
||||||
(dc/transact conn {:tx-data (for [square-location (client-locations client)]
|
@(dc/transact conn (for [square-location (client-locations client)]
|
||||||
{:db/id (or (square-id->id (:id square-location)) (random-tempid))
|
{:db/id (or (square-id->id (:id square-location)) (random-tempid))
|
||||||
:client/_square-locations (:db/id client)
|
:client/_square-locations (:db/id client)
|
||||||
:square-location/name (:name square-location)
|
:square-location/name (:name square-location)
|
||||||
:square-location/square-id (:id square-location)})}))))
|
:square-location/square-id (:id square-location)})))))
|
||||||
|
|
||||||
#_{:clj-kondo/ignore [:clojure-lsp/unused-public-var]}
|
#_{:clj-kondo/ignore [:clojure-lsp/unused-public-var]}
|
||||||
(defn reset []
|
(defn reset []
|
||||||
(->>
|
(->>
|
||||||
(dc/q {:query {:find ['?e]
|
(dc/q {:find ['?e]
|
||||||
:in ['$]
|
:in ['$]
|
||||||
:where ['(or [?e :sales-order/date]
|
:where ['(or [?e :sales-order/date]
|
||||||
[?e :expected-deposit/date])]}
|
[?e :expected-deposit/date])]}
|
||||||
:args [(dc/db conn)]})
|
(dc/db conn))
|
||||||
(map first)
|
(map first)
|
||||||
(map (fn [x] [:db/retractEntity x]))))
|
(map (fn [x] [:db/retractEntity x]))))
|
||||||
|
|
||||||
(defn mark-integration-status [client integration-status]
|
(defn mark-integration-status [client integration-status]
|
||||||
(dc/transact conn
|
@(dc/transact conn
|
||||||
{:tx-data [{:db/id (:db/id client)
|
[{:db/id (:db/id client)
|
||||||
:client/square-integration-status (assoc integration-status
|
:client/square-integration-status (assoc integration-status
|
||||||
:db/id (or (-> client :client/square-integration-status :db/id)
|
:db/id (or (-> client :client/square-integration-status :db/id)
|
||||||
(random-tempid)))}]}))
|
(random-tempid)))}]))
|
||||||
|
|
||||||
(defn upsert-all [ & clients]
|
(defn upsert-all [ & clients]
|
||||||
(doseq [client (apply get-square-clients clients)
|
(doseq [client (apply get-square-clients clients)
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
[clojure.string :as str]
|
[clojure.string :as str]
|
||||||
[clojure.tools.logging :as log]
|
[clojure.tools.logging :as log]
|
||||||
[cemerick.url :as url]
|
[cemerick.url :as url]
|
||||||
[datomic.client.api :as dc]
|
[datomic.api :as dc]
|
||||||
[slingshot.slingshot :refer [try+]]
|
[slingshot.slingshot :refer [try+]]
|
||||||
[unilog.context :as lc]))
|
[unilog.context :as lc]))
|
||||||
|
|
||||||
@@ -399,7 +399,7 @@
|
|||||||
(lc/with-context {:source "Square loading"}
|
(lc/with-context {:source "Square loading"}
|
||||||
(doseq [x (partition-all 20 (daily-results client location start end))]
|
(doseq [x (partition-all 20 (daily-results client location start end))]
|
||||||
(log/info "Loading " (count x))
|
(log/info "Loading " (count x))
|
||||||
(dc/transact conn {:tx-data x})))))
|
@(dc/transact conn x)))))
|
||||||
|
|
||||||
(defn upsert-settlements
|
(defn upsert-settlements
|
||||||
([client]
|
([client]
|
||||||
@@ -411,7 +411,7 @@
|
|||||||
:client (:client/code client)}
|
:client (:client/code client)}
|
||||||
(doseq [x (partition-all 20 (daily-settlements client location))]
|
(doseq [x (partition-all 20 (daily-settlements client location))]
|
||||||
(log/info "Loading expected deposit" (count x))
|
(log/info "Loading expected deposit" (count x))
|
||||||
(dc/transact conn {:tx-data x}))
|
@(dc/transact conn x))
|
||||||
(log/info "Done loading settlements"))))
|
(log/info "Done loading settlements"))))
|
||||||
|
|
||||||
(defn upsert-refunds
|
(defn upsert-refunds
|
||||||
@@ -425,7 +425,7 @@
|
|||||||
:location (:square-location/client-location client)}
|
:location (:square-location/client-location client)}
|
||||||
(doseq [x (partition-all 20 (refunds client location))]
|
(doseq [x (partition-all 20 (refunds client location))]
|
||||||
(log/info "Loading refund" (count x))
|
(log/info "Loading refund" (count x))
|
||||||
(dc/transact conn {:tx-data x}))
|
@(dc/transact conn x))
|
||||||
(log/info "Done loading refunds"))))
|
(log/info "Done loading refunds"))))
|
||||||
|
|
||||||
(def square-read [:db/id
|
(def square-read [:db/id
|
||||||
@@ -466,29 +466,29 @@
|
|||||||
[(:square-location/square-id sl)
|
[(:square-location/square-id sl)
|
||||||
(:db/id sl)])
|
(:db/id sl)])
|
||||||
(:client/square-locations client)))]
|
(:client/square-locations client)))]
|
||||||
(dc/transact conn {:tx-data (for [square-location (client-locations client)]
|
@(dc/transact conn (for [square-location (client-locations client)]
|
||||||
{:db/id (or (square-id->id (:id square-location)) (random-tempid))
|
{:db/id (or (square-id->id (:id square-location)) (random-tempid))
|
||||||
:client/_square-locations (:db/id client)
|
:client/_square-locations (:db/id client)
|
||||||
:square-location/name (:name square-location)
|
:square-location/name (:name square-location)
|
||||||
:square-location/square-id (:id square-location)})}))))
|
:square-location/square-id (:id square-location)})))))
|
||||||
|
|
||||||
#_{:clj-kondo/ignore [:clojure-lsp/unused-public-var]}
|
#_{:clj-kondo/ignore [:clojure-lsp/unused-public-var]}
|
||||||
(defn reset []
|
(defn reset []
|
||||||
(->>
|
(->>
|
||||||
(dc/q {:query {:find ['?e]
|
(dc/q {:find ['?e]
|
||||||
:in ['$]
|
:in ['$]
|
||||||
:where ['(or [?e :sales-order/date]
|
:where ['(or [?e :sales-order/date]
|
||||||
[?e :expected-deposit/date])]}
|
[?e :expected-deposit/date])]}
|
||||||
:args [(dc/db conn)]})
|
(dc/db conn))
|
||||||
(map first)
|
(map first)
|
||||||
(map (fn [x] [:db/retractEntity x]))))
|
(map (fn [x] [:db/retractEntity x]))))
|
||||||
|
|
||||||
(defn mark-integration-status [client integration-status]
|
(defn mark-integration-status [client integration-status]
|
||||||
(dc/transact conn
|
@(dc/transact conn
|
||||||
{:tx-data [{:db/id (:db/id client)
|
[{:db/id (:db/id client)
|
||||||
:client/square-integration-status (assoc integration-status
|
:client/square-integration-status (assoc integration-status
|
||||||
:db/id (or (-> client :client/square-integration-status :db/id)
|
:db/id (or (-> client :client/square-integration-status :db/id)
|
||||||
(random-tempid)))}]}))
|
(random-tempid)))}]))
|
||||||
|
|
||||||
(defn upsert-all [ & clients]
|
(defn upsert-all [ & clients]
|
||||||
(doseq [client (apply get-square-clients clients)
|
(doseq [client (apply get-square-clients clients)
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
[clojure.set :as set]
|
[clojure.set :as set]
|
||||||
[clojure.string :as str]
|
[clojure.string :as str]
|
||||||
[com.brunobonacci.mulog :as mu]
|
[com.brunobonacci.mulog :as mu]
|
||||||
[datomic.client.api :as dc]
|
[datomic.api :as dc]
|
||||||
[manifold.deferred :as de]
|
[manifold.deferred :as de]
|
||||||
[manifold.executor :as ex]
|
[manifold.executor :as ex]
|
||||||
[manifold.stream :as s]
|
[manifold.stream :as s]
|
||||||
@@ -562,7 +562,7 @@
|
|||||||
(doseq [x (partition-all 100 results)]
|
(doseq [x (partition-all 100 results)]
|
||||||
(log/info ::loading-orders
|
(log/info ::loading-orders
|
||||||
:count (count x))
|
:count (count x))
|
||||||
(dc/transact conn {:tx-data x}))))))))
|
@(dc/transact conn x))))))))
|
||||||
|
|
||||||
|
|
||||||
(defn upsert-settlements
|
(defn upsert-settlements
|
||||||
@@ -582,7 +582,7 @@
|
|||||||
(doseq [x (partition-all 20 settlements)]
|
(doseq [x (partition-all 20 settlements)]
|
||||||
(log/info ::loading-deposits
|
(log/info ::loading-deposits
|
||||||
:count (count x))
|
:count (count x))
|
||||||
(dc/transact conn {:tx-data x}))
|
@(dc/transact conn x))
|
||||||
(log/info ::done-loading-deposits)))))))
|
(log/info ::done-loading-deposits)))))))
|
||||||
|
|
||||||
(defn upsert-refunds
|
(defn upsert-refunds
|
||||||
@@ -603,7 +603,7 @@
|
|||||||
(log/info ::loading-refunds
|
(log/info ::loading-refunds
|
||||||
:count (count x)
|
:count (count x)
|
||||||
:sample (first x))
|
:sample (first x))
|
||||||
(dc/transact conn {:tx-data x}))
|
@(dc/transact conn x))
|
||||||
|
|
||||||
(catch Throwable e
|
(catch Throwable e
|
||||||
(log/error ::upsert-refunds-failed
|
(log/error ::upsert-refunds-failed
|
||||||
@@ -653,30 +653,30 @@
|
|||||||
(:client/square-locations client)))]
|
(:client/square-locations client)))]
|
||||||
(de/chain (client-locations client)
|
(de/chain (client-locations client)
|
||||||
(fn [client-locations]
|
(fn [client-locations]
|
||||||
(dc/transact conn
|
@(dc/transact conn
|
||||||
{:tx-data (for [square-location client-locations]
|
(for [square-location client-locations]
|
||||||
{:db/id (or (square-id->id (:id square-location)) (str (java.util.UUID/randomUUID)))
|
{:db/id (or (square-id->id (:id square-location)) (str (java.util.UUID/randomUUID)))
|
||||||
:client/_square-locations (:db/id client)
|
:client/_square-locations (:db/id client)
|
||||||
:square-location/name (:name square-location)
|
:square-location/name (:name square-location)
|
||||||
:square-location/square-id (:id square-location)})}))))))
|
:square-location/square-id (:id square-location)})))))))
|
||||||
|
|
||||||
#_{:clj-kondo/ignore [:clojure-lsp/unused-public-var]}
|
#_{:clj-kondo/ignore [:clojure-lsp/unused-public-var]}
|
||||||
(defn reset []
|
(defn reset []
|
||||||
(->>
|
(->>
|
||||||
(dc/q {:query {:find ['?e]
|
(dc/q {:find ['?e]
|
||||||
:in ['$]
|
:in ['$]
|
||||||
:where ['(or [?e :sales-order/date]
|
:where ['(or [?e :sales-order/date]
|
||||||
[?e :expected-deposit/date])]}
|
[?e :expected-deposit/date])]}
|
||||||
:args [(dc/db conn)]})
|
(dc/db conn))
|
||||||
(map first)
|
(map first)
|
||||||
(map (fn [x] [:db/retractEntity x]))))
|
(map (fn [x] [:db/retractEntity x]))))
|
||||||
|
|
||||||
(defn mark-integration-status [client integration-status]
|
(defn mark-integration-status [client integration-status]
|
||||||
(dc/transact conn
|
@(dc/transact conn
|
||||||
{:tx-data [{:db/id (:db/id client)
|
[{:db/id (:db/id client)
|
||||||
:client/square-integration-status (assoc integration-status
|
:client/square-integration-status (assoc integration-status
|
||||||
:db/id (or (-> client :client/square-integration-status :db/id)
|
:db/id (or (-> client :client/square-integration-status :db/id)
|
||||||
(str (java.util.UUID/randomUUID))))}]}))
|
(str (java.util.UUID/randomUUID))))}]))
|
||||||
|
|
||||||
(defn upsert-all [ & clients]
|
(defn upsert-all [ & clients]
|
||||||
(capture-context->lc
|
(capture-context->lc
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
[auto-ap.time :as atime]
|
[auto-ap.time :as atime]
|
||||||
[clj-time.coerce :as coerce]
|
[clj-time.coerce :as coerce]
|
||||||
[clojure.string :as str]
|
[clojure.string :as str]
|
||||||
[datomic.client.api :as dc]
|
[datomic.api :as dc]
|
||||||
[hiccup2.core :as hiccup]))
|
[hiccup2.core :as hiccup]))
|
||||||
|
|
||||||
(defn tx-rows->changes [history]
|
(defn tx-rows->changes [history]
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
[auto-ap.ssr.utils :refer [html-response]]
|
[auto-ap.ssr.utils :refer [html-response]]
|
||||||
[bidi.bidi :as bidi]
|
[bidi.bidi :as bidi]
|
||||||
[clojure.string :as str]
|
[clojure.string :as str]
|
||||||
[datomic.client.api :as dc]
|
[datomic.api :as dc]
|
||||||
[hiccup2.core :as hiccup]))
|
[hiccup2.core :as hiccup]))
|
||||||
|
|
||||||
(defn cannot-overwrite? [vendor]
|
(defn cannot-overwrite? [vendor]
|
||||||
@@ -210,11 +210,11 @@
|
|||||||
|
|
||||||
(defn vendor-save [{:keys [form-params identity route-params] :as request}]
|
(defn vendor-save [{:keys [form-params identity route-params] :as request}]
|
||||||
(when-not (cannot-overwrite? (dc/pull (dc/db conn) '[*] (Long/parseLong (:vendor-id route-params))))
|
(when-not (cannot-overwrite? (dc/pull (dc/db conn) '[*] (Long/parseLong (:vendor-id route-params))))
|
||||||
@(dc/transact conn {:tx-data [(remove-nils
|
@(dc/transact conn [(remove-nils
|
||||||
(-> (form-data->map form-params)
|
(-> (form-data->map form-params)
|
||||||
(assoc :db/id (Long/parseLong (:vendor-id route-params)))
|
(assoc :db/id (Long/parseLong (:vendor-id route-params)))
|
||||||
(update :vendor/legal-entity-1099-type #(some->> % (keyword "legal-entity-1099-type")))
|
(update :vendor/legal-entity-1099-type #(some->> % (keyword "legal-entity-1099-type")))
|
||||||
(update :vendor/legal-entity-tin-type #(some->> % (keyword "legal-entity-tin-type")))))]}))
|
(update :vendor/legal-entity-tin-type #(some->> % (keyword "legal-entity-tin-type")))))]))
|
||||||
(html-response
|
(html-response
|
||||||
(table request :flash-id (Long/parseLong (:vendor-id route-params)))))
|
(table request :flash-id (Long/parseLong (:vendor-id route-params)))))
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
[auto-ap.ssr.components.navbar-dropdown :refer [navbar-dropdown]]
|
[auto-ap.ssr.components.navbar-dropdown :refer [navbar-dropdown]]
|
||||||
[auto-ap.ssr.utils :refer [html-response]]
|
[auto-ap.ssr.utils :refer [html-response]]
|
||||||
[bidi.bidi :as bidi]
|
[bidi.bidi :as bidi]
|
||||||
[datomic.client.api :as dc]
|
[datomic.api :as dc]
|
||||||
[hiccup2.core :as hiccup]))
|
[hiccup2.core :as hiccup]))
|
||||||
|
|
||||||
(defn dropdown-contents [{:keys [identity]}]
|
(defn dropdown-contents [{:keys [identity]}]
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
[auto-ap.time :as atime]
|
[auto-ap.time :as atime]
|
||||||
[bidi.bidi :as bidi]
|
[bidi.bidi :as bidi]
|
||||||
[clj-time.coerce :as coerce]
|
[clj-time.coerce :as coerce]
|
||||||
[datomic.client.api :as dc]
|
[datomic.api :as dc]
|
||||||
[hiccup2.core :as hiccup]
|
[hiccup2.core :as hiccup]
|
||||||
[clj-time.core :as time]))
|
[clj-time.core :as time]))
|
||||||
|
|
||||||
@@ -110,7 +110,7 @@
|
|||||||
(let [r (dc/pull (dc/db conn)
|
(let [r (dc/pull (dc/db conn)
|
||||||
pull-expr
|
pull-expr
|
||||||
(Long/parseLong transaction-id))
|
(Long/parseLong transaction-id))
|
||||||
similar (->> {:query '[:find ?date ?do ?amt
|
similar (->> (dc/q '[:find ?date ?do ?amt
|
||||||
:in $ ?tr
|
:in $ ?tr
|
||||||
:where
|
:where
|
||||||
[(iol-ion.query/recent-date 180) ?start-date]
|
[(iol-ion.query/recent-date 180) ?start-date]
|
||||||
@@ -125,10 +125,9 @@
|
|||||||
[?a2 :transaction-account/account ?a]
|
[?a2 :transaction-account/account ?a]
|
||||||
[?t2 :transaction/description-original ?do]
|
[?t2 :transaction/description-original ?do]
|
||||||
[?t2 :transaction/amount ?amt]]
|
[?t2 :transaction/amount ?amt]]
|
||||||
:args [(dc/db conn)
|
(dc/db conn)
|
||||||
(Long/parseLong transaction-id)]
|
(Long/parseLong transaction-id))
|
||||||
:limit 5}
|
(take 5)
|
||||||
dc/q
|
|
||||||
sort
|
sort
|
||||||
reverse)]
|
reverse)]
|
||||||
(html-response [:div.modal.is-active.wide
|
(html-response [:div.modal.is-active.wide
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
#_{:clj-kondo/ignore [:unused-namespace]}
|
#_{:clj-kondo/ignore [:unused-namespace]}
|
||||||
[yang.scheduler :as scheduler]
|
[yang.scheduler :as scheduler]
|
||||||
[clj-time.coerce :as coerce]
|
[clj-time.coerce :as coerce]
|
||||||
[datomic.client.api :as dc]
|
[datomic.api :as dc]
|
||||||
[auto-ap.datomic :refer [conn]]
|
[auto-ap.datomic :refer [conn]]
|
||||||
[auto-ap.datomic.clients :as d-clients]))
|
[auto-ap.datomic.clients :as d-clients]))
|
||||||
;; switch all of this to use tokens instead of passing around client codes, particularly because the codes
|
;; switch all of this to use tokens instead of passing around client codes, particularly because the codes
|
||||||
@@ -293,7 +293,7 @@
|
|||||||
:body
|
:body
|
||||||
:providerAccount
|
:providerAccount
|
||||||
first))
|
first))
|
||||||
(dc/transact conn {:tx-data [[:db/retractEntity [:yodlee-provider-account/id id]]]}))
|
@(dc/transact conn [[:db/retractEntity [:yodlee-provider-account/id id]]]))
|
||||||
|
|
||||||
(defn upsert-accounts-tx
|
(defn upsert-accounts-tx
|
||||||
([client-code]
|
([client-code]
|
||||||
@@ -322,8 +322,8 @@
|
|||||||
|
|
||||||
(defn refresh-provider-account [client-code id]
|
(defn refresh-provider-account [client-code id]
|
||||||
(log/info "refreshing yodlee provider account id" id)
|
(log/info "refreshing yodlee provider account id" id)
|
||||||
(dc/transact conn {:tx-data (upsert-accounts-tx client-code
|
@(dc/transact conn (upsert-accounts-tx client-code
|
||||||
[(get-provider-account client-code id)])}))
|
[(get-provider-account client-code id)])))
|
||||||
|
|
||||||
(defn upsert-accounts []
|
(defn upsert-accounts []
|
||||||
(let [concurrent 20
|
(let [concurrent 20
|
||||||
@@ -341,7 +341,7 @@
|
|||||||
(async/to-chan! (d-clients/get-all)))
|
(async/to-chan! (d-clients/get-all)))
|
||||||
(let [result (async/<!! (async/into [] output-chan))]
|
(let [result (async/<!! (async/into [] output-chan))]
|
||||||
(log/info "Current yodlee state is " result)
|
(log/info "Current yodlee state is " result)
|
||||||
(dc/transact conn {:tx-data result}))))
|
@(dc/transact conn result))))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
120
src/clj/user.clj
120
src/clj/user.clj
@@ -17,7 +17,7 @@
|
|||||||
[clojure.pprint]
|
[clojure.pprint]
|
||||||
[clojure.string :as str]
|
[clojure.string :as str]
|
||||||
[config.core :refer [env]]
|
[config.core :refer [env]]
|
||||||
[datomic.client.api :as dc]
|
[datomic.api :as dc]
|
||||||
[mount.core :as mount]
|
[mount.core :as mount]
|
||||||
[nrepl.middleware.print]
|
[nrepl.middleware.print]
|
||||||
[unilog.context :as lc]
|
[unilog.context :as lc]
|
||||||
@@ -69,28 +69,29 @@
|
|||||||
#_{:clj-kondo/ignore [:clojure-lsp/unused-public-var]}
|
#_{:clj-kondo/ignore [:clojure-lsp/unused-public-var]}
|
||||||
(defn load-accounts [conn]
|
(defn load-accounts [conn]
|
||||||
(let [[header & rows] (-> "master-account-list.csv" (io/resource) io/input-stream (BOMInputStream.) (io/reader) csv/read-csv)
|
(let [[header & rows] (-> "master-account-list.csv" (io/resource) io/input-stream (BOMInputStream.) (io/reader) csv/read-csv)
|
||||||
code->existing-account (by :account/numeric-code (map first (dc/q {:query {:find ['(pull ?e [:account/numeric-code
|
code->existing-account (by :account/numeric-code (map first (dc/q {:find ['(pull ?e [:account/numeric-code
|
||||||
:db/id])]
|
:db/id])]
|
||||||
:in ['$]
|
:in ['$]
|
||||||
:where ['[?e :account/name]]}
|
:where ['[?e :account/name]]}
|
||||||
:args [(dc/db conn)]})))
|
(dc/db conn))))
|
||||||
|
|
||||||
also-merge-txes (fn [also-merge old-account-id]
|
also-merge-txes (fn [also-merge old-account-id]
|
||||||
(if old-account-id
|
(if old-account-id
|
||||||
(let [[sunset-account]
|
(let [[sunset-account]
|
||||||
(first (dc/q {:query {:find ['?a ]
|
(first (dc/q {:find ['?a ]
|
||||||
:in ['$ '?ac ]
|
:in ['$ '?ac ]
|
||||||
:where ['[?a :account/numeric-code ?ac]]}
|
:where ['[?a :account/numeric-code ?ac]]}
|
||||||
:args [(dc/db conn) also-merge ]}))]
|
(dc/db conn) also-merge))]
|
||||||
(into (mapv
|
(into (mapv
|
||||||
(fn [[entity id _]]
|
(fn [[entity id _]]
|
||||||
[:db/add entity id old-account-id])
|
[:db/add entity id old-account-id])
|
||||||
(dc/q {:query {:find ['?e '?id '?a ]
|
(dc/q {:find ['?e '?id '?a ]
|
||||||
:in ['$ '?ac ]
|
:in ['$ '?ac ]
|
||||||
:where ['[?a :account/numeric-code ?ac]
|
:where ['[?a :account/numeric-code ?ac]
|
||||||
'[?e ?at ?a]
|
'[?e ?at ?a]
|
||||||
'[?at :db/ident ?id]]}
|
'[?at :db/ident ?id]]}
|
||||||
:args [(dc/db conn) also-merge ]}))
|
(dc/db conn)
|
||||||
|
also-merge))
|
||||||
[[:db/retractEntity sunset-account]]))
|
[[:db/retractEntity sunset-account]]))
|
||||||
[]))
|
[]))
|
||||||
|
|
||||||
@@ -142,21 +143,20 @@
|
|||||||
conj
|
conj
|
||||||
[]
|
[]
|
||||||
rows)]
|
rows)]
|
||||||
(dc/transact conn {:tx-data txes})))
|
@(dc/transact conn txes)))
|
||||||
|
|
||||||
#_{:clj-kondo/ignore [:clojure-lsp/unused-public-var]}
|
#_{:clj-kondo/ignore [:clojure-lsp/unused-public-var]}
|
||||||
(defn find-bad-accounts []
|
(defn find-bad-accounts []
|
||||||
(set (map second (dc/q {:query {:find ['(pull ?x [*]) '?z]
|
(set (map second (dc/q {:find ['(pull ?x [*]) '?z]
|
||||||
:in ['$]
|
:in ['$]
|
||||||
:where ['[?e :account/numeric-code ?z]
|
:where ['[?e :account/numeric-code ?z]
|
||||||
'[(<= ?z 9999)]
|
'[(<= ?z 9999)]
|
||||||
'[?x ?a ?e]]}
|
'[?x ?a ?e]]}
|
||||||
:args [(dc/db conn)]}))))
|
(dc/db conn)))))
|
||||||
|
|
||||||
#_{:clj-kondo/ignore [:clojure-lsp/unused-public-var]}
|
#_{:clj-kondo/ignore [:clojure-lsp/unused-public-var]}
|
||||||
(defn delete-4-digit-accounts []
|
(defn delete-4-digit-accounts []
|
||||||
(dc/transact conn
|
@(dc/transact conn
|
||||||
{:tx-data
|
|
||||||
(transduce
|
(transduce
|
||||||
(comp
|
(comp
|
||||||
(map first)
|
(map first)
|
||||||
@@ -164,11 +164,11 @@
|
|||||||
[:db/retractEntity old-account-id])))
|
[:db/retractEntity old-account-id])))
|
||||||
conj
|
conj
|
||||||
[]
|
[]
|
||||||
(dc/q {:query {:find ['?e]
|
(dc/q {:find ['?e]
|
||||||
:in ['$]
|
:in ['$]
|
||||||
:where ['[?e :account/numeric-code ?z]
|
:where ['[?e :account/numeric-code ?z]
|
||||||
'[(<= ?z 9999)]]}
|
'[(<= ?z 9999)]]}
|
||||||
:args [(dc/db conn)]}))})
|
(dc/db conn))))
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -181,30 +181,30 @@
|
|||||||
(fn [acc [e z]]
|
(fn [acc [e z]]
|
||||||
(update acc z conj e))
|
(update acc z conj e))
|
||||||
{}
|
{}
|
||||||
(dc/q {:query {:find ['?e '?z]
|
(dc/q {:find ['?e '?z]
|
||||||
:in ['$]
|
:in ['$]
|
||||||
:where ['[?e :account/numeric-code ?z]]}
|
:where ['[?e :account/numeric-code ?z]]}
|
||||||
:args [(dc/db conn)]}))))
|
(dc/db conn)))))
|
||||||
|
|
||||||
#_{:clj-kondo/ignore [:clojure-lsp/unused-public-var]}
|
#_{:clj-kondo/ignore [:clojure-lsp/unused-public-var]}
|
||||||
(defn customize-accounts [customer filename]
|
(defn customize-accounts [customer filename]
|
||||||
(let [[_ & rows] (-> filename (io/resource) io/input-stream (BOMInputStream.) (io/reader) csv/read-csv)
|
(let [[_ & rows] (-> filename (io/resource) io/input-stream (BOMInputStream.) (io/reader) csv/read-csv)
|
||||||
[client-id] (first (dc/q (-> {:query {:find ['?e]
|
[client-id] (first (dc/q (-> {:find ['?e]
|
||||||
:in ['$ '?z]
|
:in ['$ '?z]
|
||||||
:where [['?e :client/code '?z]]}
|
:where [['?e :client/code '?z]]}
|
||||||
:args [(dc/db conn) customer]})))
|
(dc/db conn) customer)))
|
||||||
_ (println client-id)
|
_ (println client-id)
|
||||||
code->existing-account (by :account/numeric-code (map first (dc/q {:query {:find ['(pull ?e [:account/numeric-code
|
code->existing-account (by :account/numeric-code (map first (dc/q {:find ['(pull ?e [:account/numeric-code
|
||||||
{:account/applicability [:db/ident]}
|
{:account/applicability [:db/ident]}
|
||||||
:db/id])]
|
:db/id])]
|
||||||
:in ['$]
|
:in ['$]
|
||||||
:where ['[?e :account/name]]}
|
:where ['[?e :account/name]]}
|
||||||
:args [(dc/db conn)]})))
|
(dc/db conn))))
|
||||||
|
|
||||||
existing-account-overrides (dc/q (-> {:query {:find ['?e]
|
existing-account-overrides (dc/q {:find ['?e]
|
||||||
:in ['$ '?client-id]
|
:in ['$ '?client-id]
|
||||||
:where [['?e :account-client-override/client '?client-id]]}
|
:where [['?e :account-client-override/client '?client-id]]}
|
||||||
:args [(dc/db conn) client-id]}))
|
(dc/db conn) client-id)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -271,7 +271,7 @@
|
|||||||
#_{:clj-kondo/ignore [:clojure-lsp/unused-public-var]}
|
#_{:clj-kondo/ignore [:clojure-lsp/unused-public-var]}
|
||||||
(defn fix-transactions-without-locations [client-code location]
|
(defn fix-transactions-without-locations [client-code location]
|
||||||
(->>
|
(->>
|
||||||
(dc/q {:query {:find ['(pull ?e [*])]
|
(dc/q {:find ['(pull ?e [*])]
|
||||||
:in ['$ '?client-code]
|
:in ['$ '?client-code]
|
||||||
:where ['[?e :transaction/accounts ?ta]
|
:where ['[?e :transaction/accounts ?ta]
|
||||||
'[?e :transaction/matched-rule]
|
'[?e :transaction/matched-rule]
|
||||||
@@ -280,7 +280,7 @@
|
|||||||
'[?e :transaction/client ?c]
|
'[?e :transaction/client ?c]
|
||||||
'[?c :client/code ?client-code]
|
'[?c :client/code ?client-code]
|
||||||
]}
|
]}
|
||||||
:args [(dc/db conn) client-code]})
|
(dc/db conn) client-code)
|
||||||
(mapcat
|
(mapcat
|
||||||
(fn [[{:transaction/keys [accounts]}]]
|
(fn [[{:transaction/keys [accounts]}]]
|
||||||
(mapv
|
(mapv
|
||||||
@@ -293,66 +293,6 @@
|
|||||||
)
|
)
|
||||||
vec))
|
vec))
|
||||||
|
|
||||||
;; TODO uncommenting the two below this makes lein build not work, probably related to the ledger
|
|
||||||
#_(defn patch-missing-ledger-entries []
|
|
||||||
@(d/transact
|
|
||||||
(d/connect uri)
|
|
||||||
(mapv
|
|
||||||
#(l/entity-change->ledger (d/db (d/connect uri)) [:transaction %])
|
|
||||||
(concat
|
|
||||||
(->>
|
|
||||||
(d/query {:query {:find ['?t ]
|
|
||||||
:in ['$]
|
|
||||||
:where ['[?t :transaction/date]
|
|
||||||
'(not [?t :transaction/approval-status :transaction-approval-status/excluded])
|
|
||||||
'(not-join [?t] [?e :journal-entry/original-entity ?t])]}
|
|
||||||
:args [(d/db (d/connect uri))]})
|
|
||||||
(map first))))))
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#_(defn check-for-out-of-date-ledger [code]
|
|
||||||
[(d/query {:query {:find ['(count ?e)]
|
|
||||||
:in ['$ '?code]
|
|
||||||
:where ['[?e :transaction/accounts ?ta]
|
|
||||||
'[?e :transaction/matched-rule]
|
|
||||||
'[?e :transaction/approval-status :transaction-approval-status/approved]
|
|
||||||
'(not [?ta :transaction-account/location])
|
|
||||||
'[?e :transaction/client ?c]
|
|
||||||
'[?c :client/code ?code]
|
|
||||||
]}
|
|
||||||
:args [(d/db (d/connect uri)) code]})
|
|
||||||
|
|
||||||
(d/query {:query {:find ['?t ]
|
|
||||||
:in ['$]
|
|
||||||
:where ['[?t :transaction/date]
|
|
||||||
'[?t :transaction/client ?c]
|
|
||||||
'[?c :client/code ?code]
|
|
||||||
'(not [?t :transaction/approval-status :transaction-approval-status/excluded])
|
|
||||||
'(not-join [?t] [?e :journal-entry/original-entity ?t])]}
|
|
||||||
:args [(d/db (d/connect uri))]})
|
|
||||||
|
|
||||||
(d/query {:query {:find ['?t ]
|
|
||||||
:in ['$]
|
|
||||||
:where ['[?t :transaction/date]
|
|
||||||
'[?t :transaction/client ?c]
|
|
||||||
'[?c :client/code ?code]
|
|
||||||
'(not [?t :transaction/approval-status :transaction-approval-status/excluded])
|
|
||||||
'[?t :transaction/vendor ?v]
|
|
||||||
'[?j :journal-entry/original-entity ?t]
|
|
||||||
'(not [?j :journal-entry/vendor ?v])
|
|
||||||
#_'(not-join [?t] [?e :journal-entry/original-entity ?t])]}
|
|
||||||
:args [(d/db (d/connect uri))]})
|
|
||||||
|
|
||||||
(d/query {:query {:find ['(count ?i) ]
|
|
||||||
:in ['$]
|
|
||||||
:where ['[?i :invoice/client ?c]
|
|
||||||
'(not [?i :invoice/status :invoice-status/voided])
|
|
||||||
'[?c :client/code ?code]
|
|
||||||
'(not-join [?i] [?e :journal-entry/original-entity ?i])]}
|
|
||||||
:args [(d/db (d/connect uri))]})])
|
|
||||||
|
|
||||||
|
|
||||||
#_{:clj-kondo/ignore [:clojure-lsp/unused-public-var]}
|
#_{:clj-kondo/ignore [:clojure-lsp/unused-public-var]}
|
||||||
(defn go []
|
(defn go []
|
||||||
(require '[mount.core :as mount])
|
(require '[mount.core :as mount])
|
||||||
@@ -362,21 +302,21 @@
|
|||||||
#_{:clj-kondo/ignore [:clojure-lsp/unused-public-var]}
|
#_{:clj-kondo/ignore [:clojure-lsp/unused-public-var]}
|
||||||
(defn entity-history [i]
|
(defn entity-history [i]
|
||||||
(vec (sort-by first (dc/q
|
(vec (sort-by first (dc/q
|
||||||
{:query {:find ['?tx '?z '?v ]
|
{:find ['?tx '?z '?v ]
|
||||||
:in ['?i '$]
|
:in ['?i '$]
|
||||||
:where ['[?i ?a ?v ?tx ?ad]
|
:where ['[?i ?a ?v ?tx ?ad]
|
||||||
'[?a :db/ident ?z]
|
'[?a :db/ident ?z]
|
||||||
'[(= ?ad true)]]}
|
'[(= ?ad true)]]}
|
||||||
:args [i (dc/history (dc/db conn))]}))))
|
i (dc/history (dc/db conn))))))
|
||||||
|
|
||||||
#_{:clj-kondo/ignore [:clojure-lsp/unused-public-var]}
|
#_{:clj-kondo/ignore [:clojure-lsp/unused-public-var]}
|
||||||
(defn entity-history-with-revert [i]
|
(defn entity-history-with-revert [i]
|
||||||
(vec (sort-by first (dc/q
|
(vec (sort-by first (dc/q
|
||||||
{:query {:find ['?tx '?z '?v '?ad ]
|
{:find ['?tx '?z '?v '?ad ]
|
||||||
:in ['?i '$]
|
:in ['?i '$]
|
||||||
:where ['[?i ?a ?v ?tx ?ad]
|
:where ['[?i ?a ?v ?tx ?ad]
|
||||||
'[?a :db/ident ?z]]}
|
'[?a :db/ident ?z]]}
|
||||||
:args [i (dc/history (dc/db conn))]}))))
|
i (dc/history (dc/db conn))))))
|
||||||
|
|
||||||
#_{:clj-kondo/ignore [:clojure-lsp/unused-public-var]}
|
#_{:clj-kondo/ignore [:clojure-lsp/unused-public-var]}
|
||||||
(defn tx-detail [i]
|
(defn tx-detail [i]
|
||||||
@@ -397,7 +337,7 @@
|
|||||||
#_{:clj-kondo/ignore [:clojure-lsp/unused-public-var]}
|
#_{:clj-kondo/ignore [:clojure-lsp/unused-public-var]}
|
||||||
(defn start-db []
|
(defn start-db []
|
||||||
(mu/start-publisher! {:type :dev})
|
(mu/start-publisher! {:type :dev})
|
||||||
(mount.core/start (mount.core/only #{#'auto-ap.datomic/conn #'auto-ap.datomic/client})))
|
(mount.core/start (mount.core/only #{#'auto-ap.datomic/conn })))
|
||||||
|
|
||||||
(defn start-search []
|
(defn start-search []
|
||||||
(mount.core/start (mount.core/only #{#'auto-ap.graphql.vendors/indexer #'auto-ap.graphql.accounts/indexer})))
|
(mount.core/start (mount.core/only #{#'auto-ap.graphql.vendors/indexer #'auto-ap.graphql.accounts/indexer})))
|
||||||
@@ -405,7 +345,7 @@
|
|||||||
(defn restart-db []
|
(defn restart-db []
|
||||||
#_(require 'datomic.dev-local)
|
#_(require 'datomic.dev-local)
|
||||||
#_(datomic.dev-local/release-db {:system "dev" :db-name "prod-migration"})
|
#_(datomic.dev-local/release-db {:system "dev" :db-name "prod-migration"})
|
||||||
(mount.core/stop (mount.core/only #{#'auto-ap.datomic/conn #'auto-ap.datomic/client}))
|
(mount.core/stop (mount.core/only #{#'auto-ap.datomic/conn }))
|
||||||
(start-db))
|
(start-db))
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
[auto-ap.import.transactions :as sut]
|
[auto-ap.import.transactions :as sut]
|
||||||
[auto-ap.integration.util :refer [wrap-setup]]
|
[auto-ap.integration.util :refer [wrap-setup]]
|
||||||
[iol-ion.tx :refer [upsert-transaction]]
|
[iol-ion.tx :refer [upsert-transaction]]
|
||||||
[datomic.client.api :as dc]
|
[datomic.api :as dc]
|
||||||
[clj-time.coerce :as coerce]
|
[clj-time.coerce :as coerce]
|
||||||
[clojure.test :as t]
|
[clojure.test :as t]
|
||||||
[digest :as di]))
|
[digest :as di]))
|
||||||
@@ -78,12 +78,12 @@
|
|||||||
(t/testing "Should import and code transactions"
|
(t/testing "Should import and code transactions"
|
||||||
(t/testing "Should import one transaction"
|
(t/testing "Should import one transaction"
|
||||||
(let [{:strs [bank-account-id client-id]} (:tempids (dc/transact conn
|
(let [{:strs [bank-account-id client-id]} (:tempids (dc/transact conn
|
||||||
{:tx-data [{:db/id "bank-account-id"
|
[{:db/id "bank-account-id"
|
||||||
:bank-account/code "TEST-1"}
|
:bank-account/code "TEST-1"}
|
||||||
{:db/id "client-id"
|
{:db/id "client-id"
|
||||||
:client/code "TEST"
|
:client/code "TEST"
|
||||||
:client/locations ["Z" "E"]
|
:client/locations ["Z" "E"]
|
||||||
:client/bank-accounts ["bank-account-id"]}]}))
|
:client/bank-accounts ["bank-account-id"]}]))
|
||||||
result (sut/transaction->txs base-transaction
|
result (sut/transaction->txs base-transaction
|
||||||
(dc/pull (dc/db conn) sut/bank-account-pull bank-account-id)
|
(dc/pull (dc/db conn) sut/bank-account-pull bank-account-id)
|
||||||
noop-rule)]
|
noop-rule)]
|
||||||
@@ -94,7 +94,7 @@
|
|||||||
result))))
|
result))))
|
||||||
|
|
||||||
(t/testing "Should match an uncleared check"
|
(t/testing "Should match an uncleared check"
|
||||||
(let [{:strs [bank-account-id payment-id]} (->> {:tx-data [#:payment {:status :payment-status/pending
|
(let [{:strs [bank-account-id payment-id]} (->> [#:payment {:status :payment-status/pending
|
||||||
:date #inst "2019-01-01"
|
:date #inst "2019-01-01"
|
||||||
:bank-account "bank-account-id"
|
:bank-account "bank-account-id"
|
||||||
:client "client-id"
|
:client "client-id"
|
||||||
@@ -105,7 +105,7 @@
|
|||||||
:db/id "bank-account-id"}
|
:db/id "bank-account-id"}
|
||||||
#:client {:name "Client"
|
#:client {:name "Client"
|
||||||
:db/id "client-id"
|
:db/id "client-id"
|
||||||
:bank-accounts ["bank-account-id"]}]}
|
:bank-accounts ["bank-account-id"]}]
|
||||||
(dc/transact conn)
|
(dc/transact conn)
|
||||||
:tempids)]
|
:tempids)]
|
||||||
|
|
||||||
@@ -132,7 +132,7 @@
|
|||||||
(:transaction/payment transaction-result)))))
|
(:transaction/payment transaction-result)))))
|
||||||
|
|
||||||
(t/testing "Should not match an already matched check"
|
(t/testing "Should not match an already matched check"
|
||||||
(dc/transact conn {:tx-data [{:db/id payment-id :payment/status :payment-status/cleared}]})
|
(dc/transact conn [{:db/id payment-id :payment/status :payment-status/cleared}])
|
||||||
(let [result (sut/transaction->txs (assoc base-transaction
|
(let [result (sut/transaction->txs (assoc base-transaction
|
||||||
:transaction/description-original "CHECK 10001"
|
:transaction/description-original "CHECK 10001"
|
||||||
:transaction/amount -30.0)
|
:transaction/amount -30.0)
|
||||||
@@ -144,7 +144,7 @@
|
|||||||
|
|
||||||
|
|
||||||
(t/testing "Should match expected-deposits"
|
(t/testing "Should match expected-deposits"
|
||||||
(let [{:strs [bank-account-id client-id expected-deposit-id]} (->> {:tx-data [#:expected-deposit {:client "client-id"
|
(let [{:strs [bank-account-id client-id expected-deposit-id]} (->> [#:expected-deposit {:client "client-id"
|
||||||
:date #inst "2021-07-01T00:00:00-08:00"
|
:date #inst "2021-07-01T00:00:00-08:00"
|
||||||
:vendor :vendor/ccp-square
|
:vendor :vendor/ccp-square
|
||||||
:total 100.0
|
:total 100.0
|
||||||
@@ -156,7 +156,7 @@
|
|||||||
#:client {:name "Client"
|
#:client {:name "Client"
|
||||||
:db/id "client-id"
|
:db/id "client-id"
|
||||||
:locations ["MF"]
|
:locations ["MF"]
|
||||||
:bank-accounts ["bank-account-id"]}]}
|
:bank-accounts ["bank-account-id"]}]
|
||||||
(dc/transact conn)
|
(dc/transact conn)
|
||||||
:tempids)]
|
:tempids)]
|
||||||
|
|
||||||
@@ -250,21 +250,21 @@
|
|||||||
|
|
||||||
(t/deftest match-transaction-to-single-unfulfilled-payments
|
(t/deftest match-transaction-to-single-unfulfilled-payments
|
||||||
(t/testing "Auto-pay Invoices"
|
(t/testing "Auto-pay Invoices"
|
||||||
(let [{:strs [vendor1-id vendor2-id]} (->> {:tx-data [#:vendor {:name "Autopay vendor 1"
|
(let [{:strs [vendor1-id vendor2-id]} (->> [#:vendor {:name "Autopay vendor 1"
|
||||||
:db/id "vendor1-id"}
|
:db/id "vendor1-id"}
|
||||||
#:vendor {:name "Autopay vendor 2"
|
#:vendor {:name "Autopay vendor 2"
|
||||||
:db/id "vendor2-id"}]}
|
:db/id "vendor2-id"}]
|
||||||
(dc/transact conn)
|
(dc/transact conn)
|
||||||
:tempids)]
|
:tempids)]
|
||||||
(t/testing "Should find a single invoice that matches exactly"
|
(t/testing "Should find a single invoice that matches exactly"
|
||||||
(let [{:strs [client-id]} (->> {:tx-data [#:invoice {:status :invoice-status/paid
|
(let [{:strs [client-id]} (->> [#:invoice {:status :invoice-status/paid
|
||||||
:vendor vendor1-id
|
:vendor vendor1-id
|
||||||
:scheduled-payment #inst "2019-01-04"
|
:scheduled-payment #inst "2019-01-04"
|
||||||
:date #inst "2019-01-01"
|
:date #inst "2019-01-01"
|
||||||
:client "client-id"
|
:client "client-id"
|
||||||
:total 30.0
|
:total 30.0
|
||||||
:db/id "invoice-id"}
|
:db/id "invoice-id"}
|
||||||
#:client {:name "Client" :db/id "client-id"}]}
|
#:client {:name "Client" :db/id "client-id"}]
|
||||||
(dc/transact conn)
|
(dc/transact conn)
|
||||||
:tempids)
|
:tempids)
|
||||||
invoices-matches (sut/match-transaction-to-single-unfulfilled-autopayments -30.0 client-id)]
|
invoices-matches (sut/match-transaction-to-single-unfulfilled-autopayments -30.0 client-id)]
|
||||||
@@ -272,14 +272,13 @@
|
|||||||
))
|
))
|
||||||
|
|
||||||
(t/testing "Should not match paid invoice that isn't a scheduled payment"
|
(t/testing "Should not match paid invoice that isn't a scheduled payment"
|
||||||
(let [{:strs [client-id]} (->> {:tx-data
|
(let [{:strs [client-id]} (->> [#:invoice{:status :invoice-status/paid
|
||||||
[#:invoice{:status :invoice-status/paid
|
|
||||||
:vendor vendor1-id
|
:vendor vendor1-id
|
||||||
:date #inst "2019-01-01"
|
:date #inst "2019-01-01"
|
||||||
:client "client-id"
|
:client "client-id"
|
||||||
:total 30.0
|
:total 30.0
|
||||||
:db/id "invoice-id"}
|
:db/id "invoice-id"}
|
||||||
#:client {:name "Client" :db/id "client-id"}]}
|
#:client {:name "Client" :db/id "client-id"}]
|
||||||
(dc/transact conn)
|
(dc/transact conn)
|
||||||
:tempids)
|
:tempids)
|
||||||
invoices-matches (sut/match-transaction-to-single-unfulfilled-autopayments -30.0 client-id)]
|
invoices-matches (sut/match-transaction-to-single-unfulfilled-autopayments -30.0 client-id)]
|
||||||
@@ -287,15 +286,14 @@
|
|||||||
(t/is (= [] invoices-matches))))
|
(t/is (= [] invoices-matches))))
|
||||||
|
|
||||||
(t/testing "Should not match unpaid invoice"
|
(t/testing "Should not match unpaid invoice"
|
||||||
(let [{:strs [client-id]} (->> {:tx-data
|
(let [{:strs [client-id]} (->> [#:invoice {:status :invoice-status/unpaid
|
||||||
[#:invoice {:status :invoice-status/unpaid
|
|
||||||
:scheduled-payment #inst "2019-01-04"
|
:scheduled-payment #inst "2019-01-04"
|
||||||
:vendor vendor1-id
|
:vendor vendor1-id
|
||||||
:date #inst "2019-01-01"
|
:date #inst "2019-01-01"
|
||||||
:client "client-id"
|
:client "client-id"
|
||||||
:total 30.0
|
:total 30.0
|
||||||
:db/id "invoice-id"}
|
:db/id "invoice-id"}
|
||||||
#:client {:name "Client" :db/id "client-id"}]}
|
#:client {:name "Client" :db/id "client-id"}]
|
||||||
(dc/transact conn)
|
(dc/transact conn)
|
||||||
:tempids)
|
:tempids)
|
||||||
invoices-matches (sut/match-transaction-to-single-unfulfilled-autopayments -30.0 client-id)]
|
invoices-matches (sut/match-transaction-to-single-unfulfilled-autopayments -30.0 client-id)]
|
||||||
@@ -303,8 +301,7 @@
|
|||||||
(t/is (= [] invoices-matches))))
|
(t/is (= [] invoices-matches))))
|
||||||
|
|
||||||
(t/testing "Should not match invoice that already has a payment"
|
(t/testing "Should not match invoice that already has a payment"
|
||||||
(let [{:strs [client-id]} (->> {:tx-data
|
(let [{:strs [client-id]} (->> [#:invoice {:status :invoice-status/paid
|
||||||
[#:invoice {:status :invoice-status/paid
|
|
||||||
:scheduled-payment #inst "2019-01-04"
|
:scheduled-payment #inst "2019-01-04"
|
||||||
:vendor vendor1-id
|
:vendor vendor1-id
|
||||||
:date #inst "2019-01-01"
|
:date #inst "2019-01-01"
|
||||||
@@ -314,15 +311,14 @@
|
|||||||
{:invoice-payment/amount 30.0
|
{:invoice-payment/amount 30.0
|
||||||
:invoice-payment/invoice "invoice-id"}
|
:invoice-payment/invoice "invoice-id"}
|
||||||
#:client {:name "Client"
|
#:client {:name "Client"
|
||||||
:db/id "client-id"}]}
|
:db/id "client-id"}]
|
||||||
(dc/transact conn)
|
(dc/transact conn)
|
||||||
:tempids)
|
:tempids)
|
||||||
invoices-matches (sut/match-transaction-to-single-unfulfilled-autopayments -30.0
|
invoices-matches (sut/match-transaction-to-single-unfulfilled-autopayments -30.0
|
||||||
client-id)]
|
client-id)]
|
||||||
(t/is (= [] invoices-matches))))
|
(t/is (= [] invoices-matches))))
|
||||||
(t/testing "Should match multiple invoices for same vendor that total to transaction amount"
|
(t/testing "Should match multiple invoices for same vendor that total to transaction amount"
|
||||||
(let [{:strs [client-id]} (->> {:tx-data
|
(let [{:strs [client-id]} (->> [#:invoice {:status :invoice-status/paid
|
||||||
[#:invoice {:status :invoice-status/paid
|
|
||||||
:vendor vendor1-id
|
:vendor vendor1-id
|
||||||
:scheduled-payment #inst "2019-01-04"
|
:scheduled-payment #inst "2019-01-04"
|
||||||
:date #inst "2019-01-01"
|
:date #inst "2019-01-01"
|
||||||
@@ -336,15 +332,14 @@
|
|||||||
:client "client-id"
|
:client "client-id"
|
||||||
:total 15.0
|
:total 15.0
|
||||||
:db/id "invoice2-id"}
|
:db/id "invoice2-id"}
|
||||||
#:client {:name "Client" :db/id "client-id"}]}
|
#:client {:name "Client" :db/id "client-id"}]
|
||||||
(dc/transact conn)
|
(dc/transact conn)
|
||||||
:tempids)
|
:tempids)
|
||||||
invoices-matches (sut/match-transaction-to-single-unfulfilled-autopayments -30.0 client-id)]
|
invoices-matches (sut/match-transaction-to-single-unfulfilled-autopayments -30.0 client-id)]
|
||||||
(t/is (= 2 (count invoices-matches))
|
(t/is (= 2 (count invoices-matches))
|
||||||
(str "Expected " (vec invoices-matches) " to have a singular match of two invoices."))))
|
(str "Expected " (vec invoices-matches) " to have a singular match of two invoices."))))
|
||||||
(t/testing "Should not match if there are multiple candidate matches"
|
(t/testing "Should not match if there are multiple candidate matches"
|
||||||
(let [{:strs [client-id]} (->> {:tx-data
|
(let [{:strs [client-id]} (->> [#:invoice {:status :invoice-status/paid
|
||||||
[#:invoice {:status :invoice-status/paid
|
|
||||||
:vendor vendor1-id
|
:vendor vendor1-id
|
||||||
:scheduled-payment #inst "2019-01-04"
|
:scheduled-payment #inst "2019-01-04"
|
||||||
:date #inst "2019-01-01"
|
:date #inst "2019-01-01"
|
||||||
@@ -358,7 +353,7 @@
|
|||||||
:client "client-id"
|
:client "client-id"
|
||||||
:total 30.0
|
:total 30.0
|
||||||
:db/id "invoice2-id"}
|
:db/id "invoice2-id"}
|
||||||
#:client {:name "Client" :db/id "client-id"}]}
|
#:client {:name "Client" :db/id "client-id"}]
|
||||||
(dc/transact conn)
|
(dc/transact conn)
|
||||||
:tempids)
|
:tempids)
|
||||||
invoices-matches (sut/match-transaction-to-single-unfulfilled-autopayments -30.0 client-id)]
|
invoices-matches (sut/match-transaction-to-single-unfulfilled-autopayments -30.0 client-id)]
|
||||||
@@ -366,8 +361,7 @@
|
|||||||
(str "Expected " (vec invoices-matches) " to not match due to multiple possibilities."))))
|
(str "Expected " (vec invoices-matches) " to not match due to multiple possibilities."))))
|
||||||
|
|
||||||
(t/testing "Should not match if invoices are for different vendors"
|
(t/testing "Should not match if invoices are for different vendors"
|
||||||
(let [{:strs [client-id]} (->> {:tx-data
|
(let [{:strs [client-id]} (->> [#:invoice {:status :invoice-status/paid
|
||||||
[#:invoice {:status :invoice-status/paid
|
|
||||||
:vendor vendor1-id
|
:vendor vendor1-id
|
||||||
:scheduled-payment #inst "2019-01-04"
|
:scheduled-payment #inst "2019-01-04"
|
||||||
:date #inst "2019-01-01"
|
:date #inst "2019-01-01"
|
||||||
@@ -381,7 +375,7 @@
|
|||||||
:client "client-id"
|
:client "client-id"
|
||||||
:total 20.0
|
:total 20.0
|
||||||
:db/id "invoice2-id"}
|
:db/id "invoice2-id"}
|
||||||
#:client {:name "Client" :db/id "client-id"}]}
|
#:client {:name "Client" :db/id "client-id"}]
|
||||||
(dc/transact conn)
|
(dc/transact conn)
|
||||||
:tempids)
|
:tempids)
|
||||||
invoices-matches (sut/match-transaction-to-single-unfulfilled-autopayments -30.0 client-id)]
|
invoices-matches (sut/match-transaction-to-single-unfulfilled-autopayments -30.0 client-id)]
|
||||||
@@ -389,8 +383,7 @@
|
|||||||
(str "Expected " (vec invoices-matches) " to only consider invoices for the same vendor."))))
|
(str "Expected " (vec invoices-matches) " to only consider invoices for the same vendor."))))
|
||||||
|
|
||||||
(t/testing "Should only consider invoices chronologically"
|
(t/testing "Should only consider invoices chronologically"
|
||||||
(let [{:strs [client-id]} (->> {:tx-data
|
(let [{:strs [client-id]} (->> [#:invoice {:status :invoice-status/paid
|
||||||
[#:invoice {:status :invoice-status/paid
|
|
||||||
:vendor vendor1-id
|
:vendor vendor1-id
|
||||||
:scheduled-payment #inst "2019-01-04"
|
:scheduled-payment #inst "2019-01-04"
|
||||||
:date #inst "2019-01-01"
|
:date #inst "2019-01-01"
|
||||||
@@ -411,7 +404,7 @@
|
|||||||
:client "client-id"
|
:client "client-id"
|
||||||
:total 30.0
|
:total 30.0
|
||||||
:db/id "invoice3-id"}
|
:db/id "invoice3-id"}
|
||||||
#:client {:name "Client" :db/id "client-id"}]}
|
#:client {:name "Client" :db/id "client-id"}]
|
||||||
(dc/transact conn)
|
(dc/transact conn)
|
||||||
:tempids)]
|
:tempids)]
|
||||||
(t/is (= 2 (count (sut/match-transaction-to-single-unfulfilled-autopayments -40.0 client-id)))
|
(t/is (= 2 (count (sut/match-transaction-to-single-unfulfilled-autopayments -40.0 client-id)))
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
(:require [auto-ap.graphql :as sut]
|
(:require [auto-ap.graphql :as sut]
|
||||||
[venia.core :as v]
|
[venia.core :as v]
|
||||||
[clojure.test :as t :refer [deftest is testing use-fixtures]]
|
[clojure.test :as t :refer [deftest is testing use-fixtures]]
|
||||||
[datomic.client.api :as dc]
|
[datomic.api :as dc]
|
||||||
[auto-ap.integration.util :refer [wrap-setup admin-token user-token]]
|
[auto-ap.integration.util :refer [wrap-setup admin-token user-token]]
|
||||||
[auto-ap.datomic :refer [conn]]))
|
[auto-ap.datomic :refer [conn]]))
|
||||||
|
|
||||||
@@ -29,9 +29,8 @@
|
|||||||
(deftest transaction-page
|
(deftest transaction-page
|
||||||
(testing "transaction page"
|
(testing "transaction page"
|
||||||
(dc/transact conn
|
(dc/transact conn
|
||||||
{:tx-data
|
|
||||||
[(new-client {:db/id "client"})
|
[(new-client {:db/id "client"})
|
||||||
(new-transaction {:transaction/client "client"})]})
|
(new-transaction {:transaction/client "client"})])
|
||||||
|
|
||||||
(testing "It should find all transactions"
|
(testing "It should find all transactions"
|
||||||
(let [result (:transaction-page (:data (sut/query (admin-token) "{ transaction_page(filters: {client_id: null}) { count, start, data { id } }}")))]
|
(let [result (:transaction-page (:data (sut/query (admin-token) "{ transaction_page(filters: {client_id: null}) { count, start, data { id } }}")))]
|
||||||
@@ -49,10 +48,9 @@
|
|||||||
(deftest invoice-page
|
(deftest invoice-page
|
||||||
(testing "invoice page"
|
(testing "invoice page"
|
||||||
(dc/transact conn
|
(dc/transact conn
|
||||||
{:tx-data
|
|
||||||
[(new-client {:db/id "client"})
|
[(new-client {:db/id "client"})
|
||||||
(new-invoice {:invoice/client "client"
|
(new-invoice {:invoice/client "client"
|
||||||
:invoice/status :invoice-status/paid})]})
|
:invoice/status :invoice-status/paid})])
|
||||||
(testing "It should find all invoices"
|
(testing "It should find all invoices"
|
||||||
(let [result (first (:invoice-page (:data (sut/query (admin-token) "{ invoice_page(filters: {client_id: null, status:paid}) { count, start, invoices { id } }}"))))]
|
(let [result (first (:invoice-page (:data (sut/query (admin-token) "{ invoice_page(filters: {client_id: null, status:paid}) { count, start, invoices { id } }}"))))]
|
||||||
(is (= 1 (:count result)))
|
(is (= 1 (:count result)))
|
||||||
@@ -95,13 +93,12 @@
|
|||||||
(let [{:strs [vendor-id account-id yodlee-merchant-id]} (->
|
(let [{:strs [vendor-id account-id yodlee-merchant-id]} (->
|
||||||
(dc/transact
|
(dc/transact
|
||||||
conn
|
conn
|
||||||
{:tx-data
|
|
||||||
[{:vendor/name "Bryce's Meat Co"
|
[{:vendor/name "Bryce's Meat Co"
|
||||||
:db/id "vendor-id"}
|
:db/id "vendor-id"}
|
||||||
{:account/name "hello"
|
{:account/name "hello"
|
||||||
:db/id "account-id"}
|
:db/id "account-id"}
|
||||||
{:yodlee-merchant/name "yodlee"
|
{:yodlee-merchant/name "yodlee"
|
||||||
:db/id "yodlee-merchant-id"}]})
|
:db/id "yodlee-merchant-id"}])
|
||||||
|
|
||||||
:tempids)]
|
:tempids)]
|
||||||
(testing "it should reject rules that don't add up to 100%"
|
(testing "it should reject rules that don't add up to 100%"
|
||||||
@@ -194,7 +191,6 @@
|
|||||||
(deftest test-transaction-rule
|
(deftest test-transaction-rule
|
||||||
(testing "it should match rules"
|
(testing "it should match rules"
|
||||||
(let [matching-transaction (dc/transact conn
|
(let [matching-transaction (dc/transact conn
|
||||||
{:tx-data
|
|
||||||
[{:transaction/description-original "matching-desc"
|
[{:transaction/description-original "matching-desc"
|
||||||
:transaction/date #inst "2019-01-05T00:00:00.000-08:00"
|
:transaction/date #inst "2019-01-05T00:00:00.000-08:00"
|
||||||
:transaction/client {:client/name "1"
|
:transaction/client {:client/name "1"
|
||||||
@@ -214,7 +210,7 @@
|
|||||||
:transaction/date #inst "2019-01-15T23:23:00.000-08:00"
|
:transaction/date #inst "2019-01-15T23:23:00.000-08:00"
|
||||||
:transaction/amount 2.00
|
:transaction/amount 2.00
|
||||||
:transaction/id "2019-01-15 nonmatching-desc 2"
|
:transaction/id "2019-01-15 nonmatching-desc 2"
|
||||||
:db/id "b"}]})
|
:db/id "b"}])
|
||||||
{:strs [a b client-1 client-2 bank-account-1 bank-account-2]} (get-in matching-transaction [:tempids])
|
{:strs [a b client-1 client-2 bank-account-1 bank-account-2]} (get-in matching-transaction [:tempids])
|
||||||
a (str a)
|
a (str a)
|
||||||
b (str b)
|
b (str b)
|
||||||
@@ -253,7 +249,6 @@
|
|||||||
(deftest test-match-transaction-rule
|
(deftest test-match-transaction-rule
|
||||||
(testing "it should apply a rules"
|
(testing "it should apply a rules"
|
||||||
(let [{:strs [transaction-id transaction-rule-id uneven-transaction-rule-id]} (-> (dc/transact conn
|
(let [{:strs [transaction-id transaction-rule-id uneven-transaction-rule-id]} (-> (dc/transact conn
|
||||||
{:tx-data
|
|
||||||
[{:transaction/description-original "matching-desc"
|
[{:transaction/description-original "matching-desc"
|
||||||
:transaction/date #inst "2019-01-05T00:00:00.000-08:00"
|
:transaction/date #inst "2019-01-05T00:00:00.000-08:00"
|
||||||
:transaction/client {:client/name "1"
|
:transaction/client {:client/name "1"
|
||||||
@@ -280,7 +275,7 @@
|
|||||||
:transaction-rule-account/percentage 0.33333333}
|
:transaction-rule-account/percentage 0.33333333}
|
||||||
{:transaction-rule-account/location "c"
|
{:transaction-rule-account/location "c"
|
||||||
:transaction-rule-account/account {:account/numeric-code 123 :db/id "123"}
|
:transaction-rule-account/account {:account/numeric-code 123 :db/id "123"}
|
||||||
:transaction-rule-account/percentage 0.333333}]}]})
|
:transaction-rule-account/percentage 0.333333}]}])
|
||||||
:tempids)
|
:tempids)
|
||||||
rule-test (-> (sut/query (admin-token) (v/graphql-query {:venia/operation {:operation/type :mutation
|
rule-test (-> (sut/query (admin-token) (v/graphql-query {:venia/operation {:operation/type :mutation
|
||||||
:operation/name "MatchTransactionRules"}
|
:operation/name "MatchTransactionRules"}
|
||||||
|
|||||||
@@ -3,19 +3,19 @@
|
|||||||
[auto-ap.datomic :refer [conn]]
|
[auto-ap.datomic :refer [conn]]
|
||||||
[auto-ap.graphql.accounts :as sut]
|
[auto-ap.graphql.accounts :as sut]
|
||||||
[auto-ap.integration.util :refer [admin-token user-token wrap-setup]]
|
[auto-ap.integration.util :refer [admin-token user-token wrap-setup]]
|
||||||
[datomic.client.api :as dc]
|
[datomic.api :as dc]
|
||||||
[clojure.test :as t :refer [deftest is testing use-fixtures]]))
|
[clojure.test :as t :refer [deftest is testing use-fixtures]]))
|
||||||
|
|
||||||
(use-fixtures :each wrap-setup)
|
(use-fixtures :each wrap-setup)
|
||||||
|
|
||||||
(deftest test-account-search
|
(deftest test-account-search
|
||||||
(testing "It should find matching account names"
|
(testing "It should find matching account names"
|
||||||
(dc/transact conn {:tx-data [{:account/name "Food Research"
|
(dc/transact conn [{:account/name "Food Research"
|
||||||
:db/ident :client-specific-account
|
:db/ident :client-specific-account
|
||||||
:account/numeric-code 51100
|
:account/numeric-code 51100
|
||||||
:account/search-terms "Food Research"
|
:account/search-terms "Food Research"
|
||||||
:account/applicability :account-applicability/global
|
:account/applicability :account-applicability/global
|
||||||
:account/default-allowance :allowance/allowed}]})
|
:account/default-allowance :allowance/allowed}])
|
||||||
(sut/rebuild-search-index)
|
(sut/rebuild-search-index)
|
||||||
(is (> (count (sut/search {:id (admin-token)}
|
(is (> (count (sut/search {:id (admin-token)}
|
||||||
{:query "Food Research"}
|
{:query "Food Research"}
|
||||||
@@ -29,12 +29,12 @@
|
|||||||
))
|
))
|
||||||
1)))
|
1)))
|
||||||
(testing "It should filter out accounts that are not allowed for clients"
|
(testing "It should filter out accounts that are not allowed for clients"
|
||||||
(dc/transact conn {:tx-data [{:account/name "CLIENT SPECIFIC"
|
(dc/transact conn [{:account/name "CLIENT SPECIFIC"
|
||||||
:db/ident :client-specific-account
|
:db/ident :client-specific-account
|
||||||
:account/numeric-code 99999
|
:account/numeric-code 99999
|
||||||
:account/search-terms "CLIENTSPECIFIC"
|
:account/search-terms "CLIENTSPECIFIC"
|
||||||
:account/applicability :account-applicability/customized
|
:account/applicability :account-applicability/customized
|
||||||
:account/default-allowance :allowance/allowed}]})
|
:account/default-allowance :allowance/allowed}])
|
||||||
(sut/rebuild-search-index)
|
(sut/rebuild-search-index)
|
||||||
(is (= [] (sut/search {:id (admin-token)}
|
(is (= [] (sut/search {:id (admin-token)}
|
||||||
{:query "CLIENTSPECIFIC"}
|
{:query "CLIENTSPECIFIC"}
|
||||||
@@ -42,12 +42,12 @@
|
|||||||
)))
|
)))
|
||||||
|
|
||||||
(testing "It should show up for the client specific version"
|
(testing "It should show up for the client specific version"
|
||||||
(let [client-id (-> (dc/transact conn {:tx-data [{:client/name "CLIENT"
|
(let [client-id (-> (dc/transact conn [{:client/name "CLIENT"
|
||||||
:db/id "client"}
|
:db/id "client"}
|
||||||
{:db/ident :client-specific-account
|
{:db/ident :client-specific-account
|
||||||
:account/client-overrides [{:account-client-override/client "client"
|
:account/client-overrides [{:account-client-override/client "client"
|
||||||
:account-client-override/name "HI"
|
:account-client-override/name "HI"
|
||||||
:account-client-override/search-terms "HELLOWORLD"}]}]})
|
:account-client-override/search-terms "HELLOWORLD"}]}])
|
||||||
:tempids
|
:tempids
|
||||||
(get "client"))]
|
(get "client"))]
|
||||||
(sut/rebuild-search-index)
|
(sut/rebuild-search-index)
|
||||||
@@ -57,14 +57,14 @@
|
|||||||
nil))))))
|
nil))))))
|
||||||
|
|
||||||
(testing "It should hide accounts that arent applicable"
|
(testing "It should hide accounts that arent applicable"
|
||||||
(dc/transact conn {:tx-data [{:account/name "DENIED"
|
(dc/transact conn [{:account/name "DENIED"
|
||||||
:db/ident :denied-account
|
:db/ident :denied-account
|
||||||
:account/numeric-code 99998
|
:account/numeric-code 99998
|
||||||
:account/search-terms "DENIED"
|
:account/search-terms "DENIED"
|
||||||
:account/applicability :account-applicability/global
|
:account/applicability :account-applicability/global
|
||||||
:account/default-allowance :allowance/denied
|
:account/default-allowance :allowance/denied
|
||||||
:account/vendor-allowance :allowance/denied
|
:account/vendor-allowance :allowance/denied
|
||||||
:account/invoice-allowance :allowance/denied}]})
|
:account/invoice-allowance :allowance/denied}])
|
||||||
(is (= 0 (count (sut/search {:id (admin-token)}
|
(is (= 0 (count (sut/search {:id (admin-token)}
|
||||||
{:query "DENIED"}
|
{:query "DENIED"}
|
||||||
nil))))
|
nil))))
|
||||||
@@ -78,14 +78,14 @@
|
|||||||
nil)))))
|
nil)))))
|
||||||
|
|
||||||
(testing "It should warn when using a warn account"
|
(testing "It should warn when using a warn account"
|
||||||
(dc/transact conn {:tx-data [{:account/name "WARNING"
|
(dc/transact conn [{:account/name "WARNING"
|
||||||
:db/ident :warn-account
|
:db/ident :warn-account
|
||||||
:account/numeric-code 99997
|
:account/numeric-code 99997
|
||||||
:account/search-terms "WARNING"
|
:account/search-terms "WARNING"
|
||||||
:account/applicability :account-applicability/global
|
:account/applicability :account-applicability/global
|
||||||
:account/default-allowance :allowance/warn
|
:account/default-allowance :allowance/warn
|
||||||
:account/vendor-allowance :allowance/warn
|
:account/vendor-allowance :allowance/warn
|
||||||
:account/invoice-allowance :allowance/warn}]})
|
:account/invoice-allowance :allowance/warn}])
|
||||||
(sut/rebuild-search-index)
|
(sut/rebuild-search-index)
|
||||||
(is (some? (:warning (first (sut/search {:id (admin-token)}
|
(is (some? (:warning (first (sut/search {:id (admin-token)}
|
||||||
{:query "WARNING"
|
{:query "WARNING"
|
||||||
@@ -100,14 +100,14 @@
|
|||||||
:allowance :vendor}
|
:allowance :vendor}
|
||||||
nil))))))
|
nil))))))
|
||||||
(testing "It should only include admin accounts for admins"
|
(testing "It should only include admin accounts for admins"
|
||||||
(dc/transact conn {:tx-data [{:account/name "ADMINONLY"
|
(dc/transact conn [{:account/name "ADMINONLY"
|
||||||
:db/ident :warn-account
|
:db/ident :warn-account
|
||||||
:account/numeric-code 99997
|
:account/numeric-code 99997
|
||||||
:account/search-terms "ADMINONLY"
|
:account/search-terms "ADMINONLY"
|
||||||
:account/applicability :account-applicability/global
|
:account/applicability :account-applicability/global
|
||||||
:account/default-allowance :allowance/admin-only
|
:account/default-allowance :allowance/admin-only
|
||||||
:account/vendor-allowance :allowance/admin-only
|
:account/vendor-allowance :allowance/admin-only
|
||||||
:account/invoice-allowance :allowance/admin-only}]})
|
:account/invoice-allowance :allowance/admin-only}])
|
||||||
(sut/rebuild-search-index)
|
(sut/rebuild-search-index)
|
||||||
(is (= 1 (count (sut/search {:id (admin-token)}
|
(is (= 1 (count (sut/search {:id (admin-token)}
|
||||||
{:query "ADMINONLY"}
|
{:query "ADMINONLY"}
|
||||||
@@ -117,8 +117,7 @@
|
|||||||
nil)))))
|
nil)))))
|
||||||
|
|
||||||
(testing "It should allow searching for vendor accounts for invoices"
|
(testing "It should allow searching for vendor accounts for invoices"
|
||||||
(let [vendor-id (-> (dc/transact conn {:tx-data
|
(let [vendor-id (-> (dc/transact conn [{:account/name "VENDORONLY"
|
||||||
[{:account/name "VENDORONLY"
|
|
||||||
:db/id "vendor-only"
|
:db/id "vendor-only"
|
||||||
:db/ident :vendor-only
|
:db/ident :vendor-only
|
||||||
:account/numeric-code 99996
|
:account/numeric-code 99996
|
||||||
@@ -129,7 +128,7 @@
|
|||||||
:account/invoice-allowance :allowance/denied}
|
:account/invoice-allowance :allowance/denied}
|
||||||
{:vendor/name "Allowed"
|
{:vendor/name "Allowed"
|
||||||
:vendor/default-account "vendor-only"
|
:vendor/default-account "vendor-only"
|
||||||
:db/id "vendor"}]})
|
:db/id "vendor"}])
|
||||||
:tempids
|
:tempids
|
||||||
(get "vendor"))]
|
(get "vendor"))]
|
||||||
(sut/rebuild-search-index)
|
(sut/rebuild-search-index)
|
||||||
@@ -146,11 +145,11 @@
|
|||||||
|
|
||||||
(deftest get-graphql
|
(deftest get-graphql
|
||||||
(testing "should retrieve a single account"
|
(testing "should retrieve a single account"
|
||||||
(dc/transact conn {:tx-data [{:account/numeric-code 1
|
(dc/transact conn [{:account/numeric-code 1
|
||||||
:account/default-allowance :allowance/allowed
|
:account/default-allowance :allowance/allowed
|
||||||
:account/type :account-type/asset
|
:account/type :account-type/asset
|
||||||
:account/location "A"
|
:account/location "A"
|
||||||
:account/name "Test"}]})
|
:account/name "Test"}])
|
||||||
|
|
||||||
(is (= {:name "Test",
|
(is (= {:name "Test",
|
||||||
:invoice_allowance nil,
|
:invoice_allowance nil,
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
wrap-setup]]
|
wrap-setup]]
|
||||||
[clojure.test :as t :refer [deftest is testing use-fixtures]]
|
[clojure.test :as t :refer [deftest is testing use-fixtures]]
|
||||||
[com.brunobonacci.mulog :as mu]
|
[com.brunobonacci.mulog :as mu]
|
||||||
[datomic.client.api :as d]))
|
[datomic.api :as d]))
|
||||||
|
|
||||||
(use-fixtures :each wrap-setup)
|
(use-fixtures :each wrap-setup)
|
||||||
|
|
||||||
@@ -31,7 +31,7 @@
|
|||||||
|
|
||||||
(deftest get-payment-page
|
(deftest get-payment-page
|
||||||
(testing "Should list payments"
|
(testing "Should list payments"
|
||||||
(let [{{:strs [bank-id check-id client-id]} :tempids} (d/transact conn {:tx-data [{:bank-account/code "bank"
|
(let [{{:strs [bank-id check-id client-id]} :tempids} (d/transact conn [{:bank-account/code "bank"
|
||||||
:db/id "bank-id"}
|
:db/id "bank-id"}
|
||||||
{:client/code "client"
|
{:client/code "client"
|
||||||
:db/id "client-id"}
|
:db/id "client-id"}
|
||||||
@@ -43,7 +43,7 @@
|
|||||||
:payment/amount 123.50
|
:payment/amount 123.50
|
||||||
:payment/paid-to "Someone"
|
:payment/paid-to "Someone"
|
||||||
:payment/status :payment-status/pending
|
:payment/status :payment-status/pending
|
||||||
:payment/date #inst "2022-01-01"}]})]
|
:payment/date #inst "2022-01-01"}])]
|
||||||
(is (= [ {:amount 123.5,
|
(is (= [ {:amount 123.5,
|
||||||
:type :check,
|
:type :check,
|
||||||
:bank_account {:id bank-id, :code "bank"},
|
:bank_account {:id bank-id, :code "bank"},
|
||||||
@@ -86,84 +86,84 @@
|
|||||||
|
|
||||||
(deftest void-payment
|
(deftest void-payment
|
||||||
(testing "Should void payments"
|
(testing "Should void payments"
|
||||||
(let [{{:strs [bank-id check-id client-id]} :tempids} (d/transact conn {:tx-data [{:bank-account/code "bank"
|
(let [{{:strs [bank-id check-id client-id]} :tempids} (d/transact conn [{:bank-account/code "bank"
|
||||||
:db/id "bank-id"}
|
:db/id "bank-id"}
|
||||||
{:client/code "client"
|
{:client/code "client"
|
||||||
:db/id "client-id"}
|
:db/id "client-id"}
|
||||||
(sample-payment :db/id "check-id")]})]
|
(sample-payment :db/id "check-id")])]
|
||||||
(sut/void-payment {:id (admin-token)} {:payment_id check-id} nil)
|
(sut/void-payment {:id (admin-token)} {:payment_id check-id} nil)
|
||||||
(is (= :payment-status/voided (-> (d/pull (d/db conn) [{:payment/status [:db/ident ]}] check-id)
|
(is (= :payment-status/voided (-> (d/pull (d/db conn) [{:payment/status [:db/ident ]}] check-id)
|
||||||
:payment/status
|
:payment/status
|
||||||
:db/ident)))))
|
:db/ident)))))
|
||||||
|
|
||||||
(testing "Should not void payments if account is locked"
|
(testing "Should not void payments if account is locked"
|
||||||
(let [{{:strs [check-id]} :tempids} (d/transact conn {:tx-data [{:bank-account/code "bank"
|
(let [{{:strs [check-id]} :tempids} (d/transact conn [{:bank-account/code "bank"
|
||||||
:db/id "bank-id"}
|
:db/id "bank-id"}
|
||||||
{:client/code "client"
|
{:client/code "client"
|
||||||
:db/id "client-id"
|
:db/id "client-id"
|
||||||
:client/locked-until #inst "2030-01-01"}
|
:client/locked-until #inst "2030-01-01"}
|
||||||
(sample-payment :payment/client "client-id"
|
(sample-payment :payment/client "client-id"
|
||||||
:db/id "check-id"
|
:db/id "check-id"
|
||||||
:payment/date #inst "2020-01-01")]})]
|
:payment/date #inst "2020-01-01")])]
|
||||||
(is (thrown? Exception (sut/void-payment {:id (admin-token)} {:payment_id check-id} nil))))))
|
(is (thrown? Exception (sut/void-payment {:id (admin-token)} {:payment_id check-id} nil))))))
|
||||||
|
|
||||||
(deftest void-payments
|
(deftest void-payments
|
||||||
(testing "bulk void"
|
(testing "bulk void"
|
||||||
(testing "Should bulk void payments if account is not locked"
|
(testing "Should bulk void payments if account is not locked"
|
||||||
(let [{{:strs [check-id]} :tempids} (d/transact conn {:tx-data [{:bank-account/code "bank"
|
(let [{{:strs [check-id]} :tempids} (d/transact conn [{:bank-account/code "bank"
|
||||||
:db/id "bank-id"}
|
:db/id "bank-id"}
|
||||||
{:client/code "client-new"
|
{:client/code "client-new"
|
||||||
:db/id "client-id"}
|
:db/id "client-id"}
|
||||||
(sample-payment :payment/client "client-id"
|
(sample-payment :payment/client "client-id"
|
||||||
:db/id "check-id"
|
:db/id "check-id"
|
||||||
:payment/date #inst "2020-01-01")]})]
|
:payment/date #inst "2020-01-01")])]
|
||||||
(sut/void-payments {:id (admin-token)} {:filters {:date_range {:start #inst "2000-01-01"}}} nil)
|
(sut/void-payments {:id (admin-token)} {:filters {:date_range {:start #inst "2000-01-01"}}} nil)
|
||||||
(is (= :payment-status/voided (-> (d/pull (d/db conn) '[{:payment/status [:db/ident]}] check-id)
|
(is (= :payment-status/voided (-> (d/pull (d/db conn) '[{:payment/status [:db/ident]}] check-id)
|
||||||
:payment/status
|
:payment/status
|
||||||
:db/ident)))))
|
:db/ident)))))
|
||||||
|
|
||||||
(testing "Should only void a payment if it matches filter criteria"
|
(testing "Should only void a payment if it matches filter criteria"
|
||||||
(let [{{:strs [check-id]} :tempids} (d/transact conn {:tx-data [{:bank-account/code "bank"
|
(let [{{:strs [check-id]} :tempids} (d/transact conn [{:bank-account/code "bank"
|
||||||
:db/id "bank-id"}
|
:db/id "bank-id"}
|
||||||
{:client/code "client-new"
|
{:client/code "client-new"
|
||||||
:db/id "client-id"}
|
:db/id "client-id"}
|
||||||
(sample-payment :payment/client "client-id"
|
(sample-payment :payment/client "client-id"
|
||||||
:db/id "check-id"
|
:db/id "check-id"
|
||||||
:payment/date #inst "2020-01-01")]})]
|
:payment/date #inst "2020-01-01")])]
|
||||||
(sut/void-payments {:id (admin-token)} {:filters {:date_range {:start #inst "2022-01-01"}}} nil)
|
(sut/void-payments {:id (admin-token)} {:filters {:date_range {:start #inst "2022-01-01"}}} nil)
|
||||||
(is (= :payment-status/pending (-> (d/pull (d/db conn) '[{:payment/status [:db/ident]}] check-id)
|
(is (= :payment-status/pending (-> (d/pull (d/db conn) '[{:payment/status [:db/ident]}] check-id)
|
||||||
:payment/status
|
:payment/status
|
||||||
:db/ident)))))
|
:db/ident)))))
|
||||||
|
|
||||||
(testing "Should not bulk void payments if account is locked"
|
(testing "Should not bulk void payments if account is locked"
|
||||||
(let [{{:strs [check-id]} :tempids} (d/transact conn {:tx-data [{:bank-account/code "bank"
|
(let [{{:strs [check-id]} :tempids} (d/transact conn [{:bank-account/code "bank"
|
||||||
:db/id "bank-id"}
|
:db/id "bank-id"}
|
||||||
{:client/code "client"
|
{:client/code "client"
|
||||||
:db/id "client-id"
|
:db/id "client-id"
|
||||||
:client/locked-until #inst "2030-01-01"}
|
:client/locked-until #inst "2030-01-01"}
|
||||||
(sample-payment :payment/client "client-id"
|
(sample-payment :payment/client "client-id"
|
||||||
:db/id "check-id"
|
:db/id "check-id"
|
||||||
:payment/date #inst "2020-01-01")]})]
|
:payment/date #inst "2020-01-01")])]
|
||||||
(sut/void-payments {:id (admin-token)} {:filters {:date_range {:start #inst "2000-01-01"}}} nil)
|
(sut/void-payments {:id (admin-token)} {:filters {:date_range {:start #inst "2000-01-01"}}} nil)
|
||||||
(is (= :payment-status/pending (-> (d/pull (d/db conn) '[{:payment/status [:db/ident]}] check-id)
|
(is (= :payment-status/pending (-> (d/pull (d/db conn) '[{:payment/status [:db/ident]}] check-id)
|
||||||
:payment/status
|
:payment/status
|
||||||
:db/ident)))))
|
:db/ident)))))
|
||||||
|
|
||||||
(testing "Only admins should be able to bulk void"
|
(testing "Only admins should be able to bulk void"
|
||||||
(let [{{:strs [check-id]} :tempids} (d/transact conn {:tx-data [{:bank-account/code "bank"
|
(let [{{:strs [check-id]} :tempids} (d/transact conn [{:bank-account/code "bank"
|
||||||
:db/id "bank-id"}
|
:db/id "bank-id"}
|
||||||
{:client/code "client"
|
{:client/code "client"
|
||||||
:db/id "client-id"}
|
:db/id "client-id"}
|
||||||
(sample-payment :payment/client "client-id"
|
(sample-payment :payment/client "client-id"
|
||||||
:db/id "check-id"
|
:db/id "check-id"
|
||||||
:payment/date #inst "2020-01-01")]})]
|
:payment/date #inst "2020-01-01")])]
|
||||||
(is (thrown? Exception (sut/void-payments {:id (user-token)} {:filters {:date_range {:start #inst "2000-01-01"}}} nil)))))))
|
(is (thrown? Exception (sut/void-payments {:id (user-token)} {:filters {:date_range {:start #inst "2000-01-01"}}} nil)))))))
|
||||||
|
|
||||||
|
|
||||||
(deftest print-checks
|
(deftest print-checks
|
||||||
(testing "Print checks"
|
(testing "Print checks"
|
||||||
(testing "Should allow 'printing' cash checks"
|
(testing "Should allow 'printing' cash checks"
|
||||||
(let [{{:strs [invoice-id client-id bank-id]} :tempids} (d/transact conn {:tx-data [{:client/code "client"
|
(let [{{:strs [invoice-id client-id bank-id]} :tempids} (d/transact conn [{:client/code "client"
|
||||||
:db/id "client-id"
|
:db/id "client-id"
|
||||||
:client/locked-until #inst "2030-01-01"
|
:client/locked-until #inst "2030-01-01"
|
||||||
:client/bank-accounts [{:bank-account/code "bank"
|
:client/bank-accounts [{:bank-account/code "bank"
|
||||||
@@ -182,7 +182,7 @@
|
|||||||
:invoice/outstanding-balance 30.0
|
:invoice/outstanding-balance 30.0
|
||||||
:invoice/expense-accounts [{:db/id "invoice-expense-account"
|
:invoice/expense-accounts [{:db/id "invoice-expense-account"
|
||||||
:invoice-expense-account/account "account-id"
|
:invoice-expense-account/account "account-id"
|
||||||
:invoice-expense-account/amount 30.0}]}]})]
|
:invoice-expense-account/amount 30.0}]}])]
|
||||||
(let [paid-invoice (-> (sut/print-checks {:id (admin-token)} {:invoice_payments [{:invoice_id invoice-id
|
(let [paid-invoice (-> (sut/print-checks {:id (admin-token)} {:invoice_payments [{:invoice_id invoice-id
|
||||||
:amount 30.0}]
|
:amount 30.0}]
|
||||||
:client_id client-id
|
:client_id client-id
|
||||||
@@ -211,7 +211,7 @@
|
|||||||
:id))))))))
|
:id))))))))
|
||||||
|
|
||||||
(testing "Should allow 'printing' debit checks"
|
(testing "Should allow 'printing' debit checks"
|
||||||
(let [{{:strs [invoice-id client-id bank-id]} :tempids} (d/transact conn {:tx-data [{:client/code "client"
|
(let [{{:strs [invoice-id client-id bank-id]} :tempids} (d/transact conn [{:client/code "client"
|
||||||
:db/id "client-id"
|
:db/id "client-id"
|
||||||
:client/bank-accounts [{:bank-account/code "bank"
|
:client/bank-accounts [{:bank-account/code "bank"
|
||||||
:db/id "bank-id"}]}
|
:db/id "bank-id"}]}
|
||||||
@@ -229,7 +229,7 @@
|
|||||||
:invoice/outstanding-balance 50.0
|
:invoice/outstanding-balance 50.0
|
||||||
:invoice/expense-accounts [{:db/id "invoice-expense-account"
|
:invoice/expense-accounts [{:db/id "invoice-expense-account"
|
||||||
:invoice-expense-account/account "account-id"
|
:invoice-expense-account/account "account-id"
|
||||||
:invoice-expense-account/amount 50.0}]}]})]
|
:invoice-expense-account/amount 50.0}]}])]
|
||||||
(let [paid-invoice (-> (sut/print-checks {:id (admin-token)} {:invoice_payments [{:invoice_id invoice-id
|
(let [paid-invoice (-> (sut/print-checks {:id (admin-token)} {:invoice_payments [{:invoice_id invoice-id
|
||||||
:amount 50.0}]
|
:amount 50.0}]
|
||||||
:client_id client-id
|
:client_id client-id
|
||||||
@@ -258,7 +258,7 @@
|
|||||||
:id)))))))))
|
:id)))))))))
|
||||||
|
|
||||||
(testing "Should allow printing checks"
|
(testing "Should allow printing checks"
|
||||||
(let [{{:strs [invoice-id client-id bank-id]} :tempids} (d/transact conn {:tx-data [{:client/code "client"
|
(let [{{:strs [invoice-id client-id bank-id]} :tempids} (d/transact conn [{:client/code "client"
|
||||||
:db/id "client-id"
|
:db/id "client-id"
|
||||||
:client/bank-accounts [{:bank-account/code "bank"
|
:client/bank-accounts [{:bank-account/code "bank"
|
||||||
:bank-account/type :bank-account-type/check
|
:bank-account/type :bank-account-type/check
|
||||||
@@ -279,7 +279,7 @@
|
|||||||
:invoice/outstanding-balance 150.0
|
:invoice/outstanding-balance 150.0
|
||||||
:invoice/expense-accounts [{:db/id "invoice-expense-account"
|
:invoice/expense-accounts [{:db/id "invoice-expense-account"
|
||||||
:invoice-expense-account/account "account-id"
|
:invoice-expense-account/account "account-id"
|
||||||
:invoice-expense-account/amount 150.0}]}]})]
|
:invoice-expense-account/amount 150.0}]}])]
|
||||||
(let [result (-> (sut/print-checks {:id (admin-token)} {:invoice_payments [{:invoice_id invoice-id
|
(let [result (-> (sut/print-checks {:id (admin-token)} {:invoice_payments [{:invoice_id invoice-id
|
||||||
:amount 150.0}]
|
:amount 150.0}]
|
||||||
:client_id client-id
|
:client_id client-id
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
[auto-ap.datomic :refer [conn pull-attr]]
|
[auto-ap.datomic :refer [conn pull-attr]]
|
||||||
[auto-ap.graphql.clients :as sut]
|
[auto-ap.graphql.clients :as sut]
|
||||||
[auto-ap.integration.util :refer [wrap-setup user-token admin-token]]
|
[auto-ap.integration.util :refer [wrap-setup user-token admin-token]]
|
||||||
[datomic.client.api :as dc]
|
[datomic.api :as dc]
|
||||||
[clojure.test :as t :refer [deftest is testing use-fixtures]]))
|
[clojure.test :as t :refer [deftest is testing use-fixtures]]))
|
||||||
|
|
||||||
(use-fixtures :each wrap-setup)
|
(use-fixtures :each wrap-setup)
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
test-invoice
|
test-invoice
|
||||||
test-vendor
|
test-vendor
|
||||||
wrap-setup]]
|
wrap-setup]]
|
||||||
[datomic.client.api :as d]))
|
[datomic.api :as d]))
|
||||||
(use-fixtures :each wrap-setup)
|
(use-fixtures :each wrap-setup)
|
||||||
|
|
||||||
(deftest test-add-invoice
|
(deftest test-add-invoice
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
[iol-ion.tx :refer [upsert-ledger]]
|
[iol-ion.tx :refer [upsert-ledger]]
|
||||||
[auto-ap.integration.util :refer [wrap-setup]]
|
[auto-ap.integration.util :refer [wrap-setup]]
|
||||||
[clojure.test :as t :refer [deftest is testing use-fixtures]]
|
[clojure.test :as t :refer [deftest is testing use-fixtures]]
|
||||||
[datomic.client.api :as d]))
|
[datomic.api :as d]))
|
||||||
|
|
||||||
(use-fixtures :each wrap-setup)
|
(use-fixtures :each wrap-setup)
|
||||||
|
|
||||||
@@ -22,7 +22,7 @@
|
|||||||
line-2-1
|
line-2-1
|
||||||
line-2-2
|
line-2-2
|
||||||
line-3-1
|
line-3-1
|
||||||
line-3-2]} (:tempids (d/transact conn {:tx-data [{:db/id "test-account-1"
|
line-3-2]} (:tempids (d/transact conn [{:db/id "test-account-1"
|
||||||
:account/type :account-type/asset}
|
:account/type :account-type/asset}
|
||||||
{:db/id "test-account-2"
|
{:db/id "test-account-2"
|
||||||
:account/type :account-type/equity}
|
:account/type :account-type/equity}
|
||||||
@@ -63,7 +63,7 @@
|
|||||||
{:db/id "line-3-2"
|
{:db/id "line-3-2"
|
||||||
:journal-entry-line/account "test-account-2"
|
:journal-entry-line/account "test-account-2"
|
||||||
:journal-entry-line/location "A"
|
:journal-entry-line/location "A"
|
||||||
:journal-entry-line/credit 150.0}]})]}))]
|
:journal-entry-line/credit 150.0}]})]))]
|
||||||
|
|
||||||
(testing "should set running-balance on ledger entries missing them"
|
(testing "should set running-balance on ledger entries missing them"
|
||||||
|
|
||||||
@@ -79,10 +79,9 @@
|
|||||||
(testing "should recompute if the data is out of date"
|
(testing "should recompute if the data is out of date"
|
||||||
|
|
||||||
(d/transact conn
|
(d/transact conn
|
||||||
{:tx-data
|
|
||||||
[{:db/id line-1-1
|
[{:db/id line-1-1
|
||||||
:journal-entry-line/dirty true
|
:journal-entry-line/dirty true
|
||||||
:journal-entry-line/running-balance 123810.23}]})
|
:journal-entry-line/running-balance 123810.23}])
|
||||||
(sut/refresh-running-balance-cache)
|
(sut/refresh-running-balance-cache)
|
||||||
|
|
||||||
(is (= [-10.0 -60.0 -210.0]
|
(is (= [-10.0 -60.0 -210.0]
|
||||||
@@ -91,20 +90,18 @@
|
|||||||
(testing "should recompute every entry after the out of date one"
|
(testing "should recompute every entry after the out of date one"
|
||||||
|
|
||||||
(d/transact conn
|
(d/transact conn
|
||||||
{:tx-data
|
|
||||||
[{:db/id line-1-1
|
[{:db/id line-1-1
|
||||||
:journal-entry-line/dirty true
|
:journal-entry-line/dirty true
|
||||||
:journal-entry-line/debit 70.0}]})
|
:journal-entry-line/debit 70.0}])
|
||||||
(sut/refresh-running-balance-cache)
|
(sut/refresh-running-balance-cache)
|
||||||
(is (= [-70.0 -120.0 -270.0]
|
(is (= [-70.0 -120.0 -270.0]
|
||||||
(map #(pull-attr (d/db conn) :journal-entry-line/running-balance %) [line-1-1 line-2-1 line-3-1]))))
|
(map #(pull-attr (d/db conn) :journal-entry-line/running-balance %) [line-1-1 line-2-1 line-3-1]))))
|
||||||
(testing "should not recompute entries that aren't dirty"
|
(testing "should not recompute entries that aren't dirty"
|
||||||
|
|
||||||
(d/transact conn
|
(d/transact conn
|
||||||
{:tx-data
|
|
||||||
[{:db/id line-1-1
|
[{:db/id line-1-1
|
||||||
:journal-entry-line/dirty false
|
:journal-entry-line/dirty false
|
||||||
:journal-entry-line/debit 90.0}]})
|
:journal-entry-line/debit 90.0}])
|
||||||
(sut/refresh-running-balance-cache)
|
(sut/refresh-running-balance-cache)
|
||||||
(is (= [-70.0 -120.0 -270.0]
|
(is (= [-70.0 -120.0 -270.0]
|
||||||
(map #(pull-attr (d/db conn) :journal-entry-line/running-balance %) [line-1-1 line-2-1 line-3-1])))
|
(map #(pull-attr (d/db conn) :journal-entry-line/running-balance %) [line-1-1 line-2-1 line-3-1])))
|
||||||
@@ -112,7 +109,6 @@
|
|||||||
)
|
)
|
||||||
(testing "changing a ledger entry should mark the line items as dirty"
|
(testing "changing a ledger entry should mark the line items as dirty"
|
||||||
(d/transact conn
|
(d/transact conn
|
||||||
{:tx-data
|
|
||||||
[`(upsert-ledger ~{:db/id journal-entry-2
|
[`(upsert-ledger ~{:db/id journal-entry-2
|
||||||
:journal-entry/date #inst "2022-01-02"
|
:journal-entry/date #inst "2022-01-02"
|
||||||
:journal-entry/client test-client
|
:journal-entry/client test-client
|
||||||
@@ -124,7 +120,7 @@
|
|||||||
{:db/id "line-2-2"
|
{:db/id "line-2-2"
|
||||||
:journal-entry-line/account test-account-2
|
:journal-entry-line/account test-account-2
|
||||||
:journal-entry-line/location "A"
|
:journal-entry-line/location "A"
|
||||||
:journal-entry-line/credit 50.0}]})]})
|
:journal-entry-line/credit 50.0}]})])
|
||||||
(is (= [true true]
|
(is (= [true true]
|
||||||
(->> (d/pull (d/db conn) '[{:journal-entry/line-items [:journal-entry-line/dirty]}] journal-entry-2)
|
(->> (d/pull (d/db conn) '[{:journal-entry/line-items [:journal-entry-line/dirty]}] journal-entry-2)
|
||||||
(:journal-entry/line-items)
|
(:journal-entry/line-items)
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
user-token
|
user-token
|
||||||
wrap-setup]]
|
wrap-setup]]
|
||||||
[clojure.test :as t :refer [deftest is testing use-fixtures]]
|
[clojure.test :as t :refer [deftest is testing use-fixtures]]
|
||||||
[datomic.client.api :as dc]))
|
[datomic.api :as dc]))
|
||||||
|
|
||||||
(use-fixtures :each wrap-setup)
|
(use-fixtures :each wrap-setup)
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
[auto-ap.integration.util :refer [admin-token user-token wrap-setup]]
|
[auto-ap.integration.util :refer [admin-token user-token wrap-setup]]
|
||||||
[clojure.test :as t :refer [deftest is testing use-fixtures]]
|
[clojure.test :as t :refer [deftest is testing use-fixtures]]
|
||||||
[com.brunobonacci.mulog :as mu]
|
[com.brunobonacci.mulog :as mu]
|
||||||
[datomic.client.api :as d]))
|
[datomic.api :as d]))
|
||||||
|
|
||||||
(use-fixtures :each wrap-setup)
|
(use-fixtures :each wrap-setup)
|
||||||
|
|
||||||
@@ -15,12 +15,12 @@
|
|||||||
(testing "should allow editing a user"
|
(testing "should allow editing a user"
|
||||||
|
|
||||||
|
|
||||||
(let [{{:strs [user-id] } :tempids} (d/transact conn {:tx-data [{:db/id "user-id" :user/name "Bryce"}]})
|
(let [{{:strs [user-id] } :tempids} (d/transact conn [{:db/id "user-id" :user/name "Bryce"}])
|
||||||
result (sut/edit-user {:id (admin-token)} {:edit_user {:role :power_user :id user-id}} nil)]
|
result (sut/edit-user {:id (admin-token)} {:edit_user {:role :power_user :id user-id}} nil)]
|
||||||
(is (some? (:id result))
|
(is (some? (:id result))
|
||||||
(= :power_user (:role result)))
|
(= :power_user (:role result)))
|
||||||
(testing "Should allow adding clients"
|
(testing "Should allow adding clients"
|
||||||
(let [{{:strs [client-id] } :tempids} (d/transact conn {:tx-data [{:db/id "client-id" :client/name "Bryce"}]})
|
(let [{{:strs [client-id] } :tempids} (d/transact conn [{:db/id "client-id" :client/name "Bryce"}])
|
||||||
result (sut/edit-user {:id (admin-token)} {:edit_user {:role :power_user
|
result (sut/edit-user {:id (admin-token)} {:edit_user {:role :power_user
|
||||||
:id user-id
|
:id user-id
|
||||||
:clients [(str client-id)]}} nil)]
|
:clients [(str client-id)]}} nil)]
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
(ns auto-ap.integration.util
|
(ns auto-ap.integration.util
|
||||||
(:require [datomic.client.api :as dc]
|
(:require [datomic.api :as dc]
|
||||||
[auto-ap.datomic :refer [client conn transact-schema]]
|
[auto-ap.datomic :refer [client conn transact-schema]]
|
||||||
[clj-time.core :as time]))
|
[clj-time.core :as time]))
|
||||||
|
|
||||||
@@ -102,7 +102,7 @@
|
|||||||
(dissoc x :id))
|
(dissoc x :id))
|
||||||
|
|
||||||
(defn setup-test-data [data]
|
(defn setup-test-data [data]
|
||||||
(:tempids (dc/transact conn {:tx-data (into data
|
(:tempids (dc/transact conn (into data
|
||||||
[(test-account :db/id "test-account-id")
|
[(test-account :db/id "test-account-id")
|
||||||
(test-client :db/id "test-client-id"
|
(test-client :db/id "test-client-id"
|
||||||
:client/bank-accounts [(test-bank-account :db/id "test-bank-account-id")])
|
:client/bank-accounts [(test-bank-account :db/id "test-bank-account-id")])
|
||||||
@@ -111,7 +111,7 @@
|
|||||||
:account/name "Accounts Payable"
|
:account/name "Accounts Payable"
|
||||||
:db/ident :account/accounts-payable
|
:db/ident :account/accounts-payable
|
||||||
:account/numeric-code 21000
|
:account/numeric-code 21000
|
||||||
:account/account-set "default"}])})))
|
:account/account-set "default"}]))))
|
||||||
|
|
||||||
(defn apply-tx [data]
|
(defn apply-tx [data]
|
||||||
(:db-after (dc/transact conn {:tx-data data})))
|
(:db-after (dc/transact conn data)))
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
[auto-ap.routes.invoices :as sut]
|
[auto-ap.routes.invoices :as sut]
|
||||||
[clj-time.coerce :as coerce]
|
[clj-time.coerce :as coerce]
|
||||||
[clojure.test :as t]
|
[clojure.test :as t]
|
||||||
[datomic.client.api :as dc]))
|
[datomic.api :as dc]))
|
||||||
|
|
||||||
(t/use-fixtures :each wrap-setup)
|
(t/use-fixtures :each wrap-setup)
|
||||||
|
|
||||||
@@ -39,7 +39,7 @@
|
|||||||
|
|
||||||
(t/deftest import-uploaded-invoices
|
(t/deftest import-uploaded-invoices
|
||||||
(t/testing "It should import one"
|
(t/testing "It should import one"
|
||||||
(dc/transact conn {:tx-data [client expense-account vendor]})
|
(dc/transact conn [client expense-account vendor])
|
||||||
(rebuild-search-index)
|
(rebuild-search-index)
|
||||||
|
|
||||||
(t/is (= 0 (invoice-count-for-client [:client/code "ABC"])))
|
(t/is (= 0 (invoice-count-for-client [:client/code "ABC"])))
|
||||||
@@ -63,18 +63,17 @@
|
|||||||
(t/is (= [["DE"]] (dc/q '[:find ?l
|
(t/is (= [["DE"]] (dc/q '[:find ?l
|
||||||
:where [?i :invoice/invoice-number "789"]
|
:where [?i :invoice/invoice-number "789"]
|
||||||
[?i :invoice/expense-accounts ?ea]
|
[?i :invoice/expense-accounts ?ea]
|
||||||
[?ea :invoice-expense-account/location ?l]]
|
[?ea :invoice-expense-account/location ?l]
|
||||||
(dc/db conn)))))
|
(dc/db conn)))))
|
||||||
|
|
||||||
(t/testing "Should code invoice"
|
(t/testing "Should code invoice"
|
||||||
(let [{{:strs [my-default-account coded-vendor]} :tempids} (dc/transact conn
|
(let [{{:strs [my-default-account coded-vendor]} :tempids} (dc/transact conn
|
||||||
{:tx-data
|
|
||||||
[{:vendor/name "Coded"
|
[{:vendor/name "Coded"
|
||||||
:db/id "coded-vendor"
|
:db/id "coded-vendor"
|
||||||
:vendor/terms 12
|
:vendor/terms 12
|
||||||
:vendor/default-account "my-default-account"}
|
:vendor/default-account "my-default-account"}
|
||||||
{:db/id "my-default-account"
|
{:db/id "my-default-account"
|
||||||
:account/name "My default-account"}]})]
|
:account/name "My default-account"}])]
|
||||||
(sut/import-uploaded-invoice user [(assoc invoice
|
(sut/import-uploaded-invoice user [(assoc invoice
|
||||||
:invoice-number "456"
|
:invoice-number "456"
|
||||||
:customer-identifier "ABC"
|
:customer-identifier "ABC"
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
[auto-ap.integration.util
|
[auto-ap.integration.util
|
||||||
:refer [apply-tx setup-test-data test-invoice test-transaction wrap-setup]]
|
:refer [apply-tx setup-test-data test-invoice test-transaction wrap-setup]]
|
||||||
[clojure.test :as t :refer [deftest is testing use-fixtures]]
|
[clojure.test :as t :refer [deftest is testing use-fixtures]]
|
||||||
[datomic.client.api :as dc]
|
[datomic.api :as dc]
|
||||||
[iol-ion.tx :as sut]))
|
[iol-ion.tx :as sut]))
|
||||||
|
|
||||||
(use-fixtures :each wrap-setup)
|
(use-fixtures :each wrap-setup)
|
||||||
|
|||||||
Reference in New Issue
Block a user