Add vendor pre-population for bulk code and individual edit forms

- Add vendor-changed HTMX handlers for both bulk code and individual edit
- Pre-populate default account at 100% when vendor is selected and no accounts exist
- Fix render-accounts-section to render from step-params correctly
- Change bulk code vendor-changed from hx-get to hx-post to include form data
- Add routes for vendor-changed endpoints
- Update e2e tests to cover vendor pre-population
- Run lein cljfmt fix across codebase
This commit is contained in:
2026-05-21 14:45:19 -07:00
parent 8bd0cee1b1
commit ba87805d4c
210 changed files with 8694 additions and 9627 deletions

View File

@@ -375,7 +375,6 @@ test.describe('Bulk Code Transactions - Account Distribution', () => {
await addNewAccount(page);
await selectAccountFromTypeahead(page, 0, 'test-account');
// "Shared" should be valid for accounts without fixed location
await setAccountLocation(page, 0, 'Shared');
await setAccountPercentage(page, 0, '100');
@@ -385,3 +384,60 @@ test.describe('Bulk Code Transactions - Account Distribution', () => {
await page.waitForSelector('table tbody tr');
});
});
test.describe('Bulk Code Transactions - Vendor Pre-population', () => {
test('should pre-populate default account when vendor is selected', async ({ page }) => {
await navigateToTransactions(page);
await selectTransactionByIndex(page, 0);
await openBulkCodeModal(page);
// Select vendor (test vendor has default-account set to test-account)
const testInfo = await getTestInfo(page);
const vendorId = testInfo.accounts.vendor;
// The vendor typeahead dispatches change from its parent div
// We need to set the hidden input and dispatch change on the container
const vendorContainer = page.locator('div[hx-post*="vendor-changed"]').first();
const vendorHidden = vendorContainer.locator('input[type="hidden"]').first();
await vendorHidden.evaluate((el: HTMLInputElement, value: string) => {
const newInput = document.createElement('input');
newInput.type = 'hidden';
newInput.name = el.name;
newInput.value = value;
el.parentNode.replaceChild(newInput, el);
}, vendorId.toString());
// Dispatch change on the container to trigger HTMX
await vendorContainer.evaluate((el: HTMLElement) => {
el.dispatchEvent(new Event('change', { bubbles: true }));
});
// Wait for HTMX response
await page.waitForResponse(response => response.url().includes('/vendor-changed') && response.status() === 200);
await page.waitForTimeout(500);
// Account should be pre-populated - check for account row
const accountRows = page.locator('#account-entries tbody tr');
const rowCount = await accountRows.count();
// Should have at least 1 account row (the default account) plus the new-row button
expect(rowCount).toBeGreaterThanOrEqual(2);
// The account should have a hidden input with the test-account ID
const accountHidden = page.locator('input[type="hidden"][name*="[account]"]').first();
const accountValue = await accountHidden.inputValue();
expect(accountValue).toBe(testInfo.accounts['test-account'].toString());
// Percentage should be 100
const percentageInput = page.locator('input[name*="percentage"]').first();
const percentageValue = await percentageInput.inputValue();
expect(percentageValue).toBe('100');
// Submit should succeed
await submitBulkCodeForm(page);
await closeBulkCodeModal(page);
await page.waitForSelector('table tbody tr');
});
});

View File

@@ -14,7 +14,7 @@
#_{:clj-kondo/ignore [:clojure-lsp/unused-public-var]}
(defn dollars= [amt1 amt2]
(dollars-0? (- amt1 amt2) ))
(dollars-0? (- amt1 amt2)))
(defn localize [d]
(time/to-time-zone d (time/time-zone-for-id "America/Los_Angeles")))
@@ -22,7 +22,6 @@
(defn local-now []
(localize (time/now)))
(defn recent-date
([]
(recent-date 90))
@@ -34,14 +33,14 @@
(->> d
(coerce/to-date-time)
localize
(f/unparse excel-formatter )))
(f/unparse excel-formatter)))
(def iso-formatter (f/with-zone (f/formatter "yyyy-MM-dd") (time/time-zone-for-id "America/Los_Angeles")))
(defn iso-date [d]
(->> d
(coerce/to-date-time)
localize
(f/unparse iso-formatter )))
(f/unparse iso-formatter)))
(defn sales-orders-in-range [db client start end]
(let [end (or end #inst "2050-01-01")]
@@ -53,9 +52,6 @@
[client start]
[client end]))))
(defn can-see-client? [identity client]
(when (not client)
(println "WARNING - permission checking for null client"))
@@ -63,11 +59,9 @@
((set (map :db/id (:user/clients identity))) (:db/id client))
((set (map :db/id (:user/clients identity))) client)))
(defn ->pattern [x]
(. java.util.regex.Pattern (compile x java.util.regex.Pattern/CASE_INSENSITIVE)))
(defn dom [^java.util.Date x]
(-> x
(.toInstant)
@@ -85,8 +79,8 @@
:let [c (entid db c)]
r (seq (dc/index-range db
:sales-order/client+date
[c (or start #inst "2001-01-01T08:00:00.000-00:00") ]
[c (or (next-day end) #inst "2030-03-05T08:00:00.000-00:00") ]))]
[c (or start #inst "2001-01-01T08:00:00.000-00:00")]
[c (or (next-day end) #inst "2030-03-05T08:00:00.000-00:00")]))]
[(:e r) (first (:v r)) (second (:v r))]))
(defn scan-charges [db clients start end]
@@ -94,8 +88,8 @@
:let [c (entid db c)]
r (seq (dc/index-range db
:charge/client+date
[c (or start #inst "2001-01-01T08:00:00.000-00:00") ]
[c (or (next-day end) #inst "2030-03-05T08:00:00.000-00:00") ]))]
[c (or start #inst "2001-01-01T08:00:00.000-00:00")]
[c (or (next-day end) #inst "2030-03-05T08:00:00.000-00:00")]))]
[(:e r) (first (:v r)) (second (:v r))]))
(defn scan-sales-refunds [db clients start end]
@@ -103,8 +97,8 @@
:let [c (entid db c)]
r (seq (dc/index-range db
:sales-refund/client+date
[c (or start #inst "2001-01-01T08:00:00.000-00:00") ]
[c (or (next-day end) #inst "2030-03-05T08:00:00.000-00:00") ]))]
[c (or start #inst "2001-01-01T08:00:00.000-00:00")]
[c (or (next-day end) #inst "2030-03-05T08:00:00.000-00:00")]))]
[(:e r) (first (:v r)) (second (:v r))]))
(defn scan-expected-deposits [db clients start end]
@@ -112,8 +106,8 @@
:let [c (entid db c)]
r (seq (dc/index-range db
:expected-deposit/client+date
[c (or start #inst "2001-01-01T08:00:00.000-00:00") ]
[c (or (next-day end) #inst "2030-03-05T08:00:00.000-00:00") ]))]
[c (or start #inst "2001-01-01T08:00:00.000-00:00")]
[c (or (next-day end) #inst "2030-03-05T08:00:00.000-00:00")]))]
[(:e r) (first (:v r)) (second (:v r))]))
(defn scan-cash-drawer-shifts [db clients start end]
@@ -121,8 +115,8 @@
:let [c (entid db c)]
r (seq (dc/index-range db
:cash-drawer-shift/client+date
[c (or start #inst "2001-01-01T08:00:00.000-00:00") ]
[c (or (next-day end) #inst "2030-03-05T08:00:00.000-00:00") ]))]
[c (or start #inst "2001-01-01T08:00:00.000-00:00")]
[c (or (next-day end) #inst "2030-03-05T08:00:00.000-00:00")]))]
[(:e r) (first (:v r)) (second (:v r))]))
(defn scan-invoices [db clients start end]
@@ -130,8 +124,8 @@
:let [c (entid db c)]
r (seq (dc/index-range db
:invoice/client+date
[c (or start #inst "2001-01-01T08:00:00.000-00:00") ]
[c (or (next-day end) #inst "2030-03-05T08:00:00.000-00:00") ]))]
[c (or start #inst "2001-01-01T08:00:00.000-00:00")]
[c (or (next-day end) #inst "2030-03-05T08:00:00.000-00:00")]))]
[(:e r) (first (:v r)) (second (:v r))]))
(defn scan-transactions [db clients start end]
@@ -139,8 +133,8 @@
:let [c (entid db c)]
r (seq (dc/index-range db
:transaction/client+date
[c (or start #inst "2001-01-01T08:00:00.000-00:00") ]
[c (or (next-day end) #inst "2030-03-05T08:00:00.000-00:00") ]))]
[c (or start #inst "2001-01-01T08:00:00.000-00:00")]
[c (or (next-day end) #inst "2030-03-05T08:00:00.000-00:00")]))]
[(:e r) (first (:v r)) (second (:v r))]))
(defn scan-ledger [db clients start end]
@@ -148,8 +142,8 @@
:let [c (entid db c)]
r (seq (dc/index-range db
:journal-entry/client+date
[c (or start #inst "2001-01-01T08:00:00.000-00:00") ]
[c (or (next-day end) #inst "2030-03-05T08:00:00.000-00:00") ]))]
[c (or start #inst "2001-01-01T08:00:00.000-00:00")]
[c (or (next-day end) #inst "2030-03-05T08:00:00.000-00:00")]))]
[(:e r) (first (:v r)) (second (:v r))]))
(defn scan-payments [db clients start end]
@@ -157,15 +151,14 @@
:let [c (entid db c)]
r (seq (dc/index-range db
:payment/client+date
[c (or start #inst "2001-01-01T08:00:00.000-00:00") ]
[c (or (next-day end) #inst "2030-03-05T08:00:00.000-00:00") ]))]
[c (or start #inst "2001-01-01T08:00:00.000-00:00")]
[c (or (next-day end) #inst "2030-03-05T08:00:00.000-00:00")]))]
[(:e r) (first (:v r)) (second (:v r))]))
(defn ident [x]
(:db/ident x))
(deftype Line [^Long id ^Long client-id ^Long account-id ^String location ^java.util.Date date ^Double debit ^Double credit ^Double running-balance]
)
(deftype Line [^Long id ^Long client-id ^Long account-id ^String location ^java.util.Date date ^Double debit ^Double credit ^Double running-balance])
(defmethod print-method Line [entity writer]
(.write writer (format "Line %d: client:%d account:%d location:%s date:%s"
@@ -175,12 +168,10 @@
(.-location entity)
(iso-date (.-date entity)))))
(defn ->line [{[current-client current-account current-location current-date debit credit running-balance]
:v
id :e}]
(Line. id current-client current-account current-location current-date debit credit running-balance)
)
(Line. id current-client current-account current-location current-date debit credit running-balance))
(defn compare-account [^Line l1 ^Line l2]
@@ -194,7 +185,7 @@
(seq)
(map ->line)
(partition-by (fn set-partition [^Line l]
[(.-account-id l) (.-location l)]))) ]
[(.-account-id l) (.-location l)])))]
(->> running-balance-set
(sort compare-account))))
@@ -205,11 +196,11 @@
(take-while (fn until-date [^Line l]
(let [^java.util.Date d (.-date l)]
(<= (.compareTo ^java.util.Date d end) 0))))
last) ]
last)]
:when (and z (.-id z))]
[(.-client-id z) (.-account-id z) (.-location z) (.-date z) (.-running-balance z)]))
#_(doseq [[ n] (dc/q '[:find ?cd :where [?c :client/code ?cd] [?c :client/groups "NTG"]] (dc/db auto-ap.datomic/conn))]
#_(doseq [[n] (dc/q '[:find ?cd :where [?c :client/code ?cd] [?c :client/groups "NTG"]] (dc/db auto-ap.datomic/conn))]
(println n)
(dc/q '[:find ?code ?name ?afc ?an ?l ?d2 ?balance
:in $ ?end ?group
@@ -269,7 +260,6 @@
(do
[client-id account-id location debits credits current-balance count sample]))))
(comment
(->>
(detailed-account-snapshot (dc/db auto-ap.datomic/conn)
@@ -280,12 +270,12 @@
(into #{})
seq)
(account-snapshot (dc/db auto-ap.datomic/conn)
(account-snapshot (dc/db auto-ap.datomic/conn)
(auto-ap.datomic/pull-id (dc/db auto-ap.datomic/conn)
[:client/code "NGOP"])
#inst "2022-01-01")
(def orig (->> [:client/code "NGOP"]
(def orig (->> [:client/code "NGOP"]
(auto-ap.datomic/pull-id (dc/db auto-ap.datomic/conn))
(account-sets (dc/db auto-ap.datomic/conn))
(mapcat (fn [ls]
@@ -293,9 +283,9 @@
(filter (fn [l] (nil? (.-location l))))
(into #{})))
(.-location orig)
(.-location orig)
(def orig (into [] (take 5000 (mapcat (fn [ls]
(def orig (into [] (take 5000 (mapcat (fn [ls]
(map #(.-id %) ls)) (account-sets (dc/db auto-ap.datomic/conn)
(auto-ap.datomic/pull-id (dc/db auto-ap.datomic/conn)
[:client/code "NGOP"]))))))
@@ -307,14 +297,14 @@
(= orig n)
#_(seq (dc/q '[:find ?c ?a ?l ?date ?balance
#_(seq (dc/q '[:find ?c ?a ?l ?date ?balance
:in $
:where [?c :client/code "NGOP"]
[(iol-ion.query/account-snapshot $ ?c #inst "2023-01-01") [?x ...]]
[(untuple ?x) [_ ?a ?l ?date ?balance]]]
(dc/db auto-ap.datomic/conn)))
#_(->> (seq (dc/q '[:find ?code ?name ?afc ?an ?l ?d2 ?balance ?end4
#_(->> (seq (dc/q '[:find ?code ?name ?afc ?an ?l ?d2 ?balance ?end4
:in $ ?end ?group
:where
[(clj-time.coerce/to-date-time ?end) ?end2]

View File

@@ -11,7 +11,6 @@
(def pull-many iol-ion.utils/pull-many)
(def remove-nils iol-ion.utils/remove-nils)
;; TODO expected-deposit ledger entry
#_(defmethod entity-change->ledger :expected-deposit
[db [type id]]
@@ -33,9 +32,6 @@
:location "A"
:account :account/ccp}]}))
(defn regenerate-literals []
(require 'com.github.ivarref.gen-fn)
(spit

View File

@@ -13,7 +13,7 @@
(:invoice/invoice-number invoice)
(:invoice/client invoice)
(:invoice/vendor invoice))))
[ locked-until] (first (dc/q '[:find ?locked-until
[locked-until] (first (dc/q '[:find ?locked-until
:in $ ?c
:where [?c :client/locked-until ?locked-until]]
db

View File

@@ -16,6 +16,6 @@
(-> []
(into (map (fn [i] (if is-component?
[:db/retractEntity i]
[:db/retract e a i ])) retract-ids))
[: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)))))

View File

@@ -12,5 +12,5 @@
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/retract e a i]) retracts))
(into (map (fn [i] [:db/add e a i]) new)))))

View File

@@ -5,7 +5,6 @@
)
(:import [java.util UUID]))
(defn -random-tempid []
(str (UUID/randomUUID)))
@@ -36,7 +35,6 @@
;; :else
;; v))
(defn upsert-entity [db entity]
(when-not (or (:db/id entity)
(:db/ident entity))

View File

@@ -7,8 +7,7 @@
(fn [m k v]
(if (not (nil? v))
(assoc m k v)
m
))
m))
{}
m)]
(if (seq result)
@@ -49,25 +48,22 @@
: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"
}
: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")
}
: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))
)}))))
(every? #(= :payment-status/cleared (:payment/status %)) (:invoice/payments entity)))}))))
(defn current-date [db]
(let [ last-tx (dc/t->tx (dc/basis-t db))
(let [last-tx (dc/t->tx (dc/basis-t db))
[[date]] (seq (dc/q '[:find ?ti :in $ ?tx
:where [?tx :db/txInstant ?ti]]
db

View File

@@ -24,9 +24,8 @@
(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 current-date [db]
(let [ last-tx (dc/t->tx (dc/basis-t db))
(let [last-tx (dc/t->tx (dc/basis-t db))
[[date]] (seq (dc/q '[:find ?ti :in $ ?tx
:where [?tx :db/txInstant ?ti]]
db
@@ -51,7 +50,7 @@
(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]))) ]
(dc/pull db extant-read [:journal-entry/external-id external-id])))]
(cond->
[[:upsert-entity (into (-> ledger-entry

View File

@@ -30,8 +30,7 @@
total-debits (reduce + 0.0 (map #(get % :ledger-side/debit 0.0) aggregated))
total-credits (reduce + 0.0 (map #(get % :ledger-side/credit 0.0) aggregated))
_ (clojure.pprint/pprint [total-debits total-credits])
]
_ (clojure.pprint/pprint [total-debits total-credits])]
(when (and (seq line-items)
(= (Math/round (* 1000 total-debits))
(Math/round (* 1000 total-credits))))
@@ -65,6 +64,5 @@ _ (clojure.pprint/pprint [total-debits total-credits])
(concat
[[:db/retractEntity [:journal-entry/original-entity (:db/id summary)]]]
(when client-id [{:db/id client-id
:client/ledger-last-change (current-date db)}]))))))

View File

@@ -81,7 +81,6 @@
[[:upsert-ledger journal-entry]]
[[:db/retractEntity [:journal-entry/original-entity (:db/id transaction)]]]))))
#_(comment
;; If transactions are failing, it is likely that there are multiple bank accounts linked
@@ -148,6 +147,4 @@
[:upsert-ledger my-journal]])
(auto-ap.datomic/pull-attr (dc/db auto-ap.datomic/conn) :bank-account/code 17592232681223)
(auto-ap.datomic/pull-attr (dc/db auto-ap.datomic/conn) :bank-account/code 17592232681228)
)
(auto-ap.datomic/pull-attr (dc/db auto-ap.datomic/conn) :bank-account/code 17592232681228))

View File

@@ -14,7 +14,7 @@
{}
xs)))
(defn pull-many [db read ids ]
(defn pull-many [db read ids]
(->> (dc/q '[:find (pull ?e r)
:in $ [?e ...] r]
db
@@ -27,8 +27,7 @@
(fn [m k v]
(if (not (nil? v))
(assoc m k v)
m
))
m))
{}
m)]
(if (seq result)

File diff suppressed because one or more lines are too long

View File

@@ -1,12 +1,11 @@
(ns amazonica.aws.textract
(:require [amazonica.core :as amz])
(:import [com.amazonaws.services.textract AmazonTextractClient ]))
(:import [com.amazonaws.services.textract AmazonTextractClient]))
#_
(import '[com.amazonaws.services.textract AmazonTextractClient ])
#_(import '[com.amazonaws.services.textract.model S3Object ])
#_(import '[com.amazonaws.services.textract.model StartExpenseAnalysisRequest ])
#_(import '[com.amazonaws.services.textract.model GetExpenseAnalysisRequest ])
#_(import '[com.amazonaws.services.textract AmazonTextractClient])
#_(import '[com.amazonaws.services.textract.model S3Object])
#_(import '[com.amazonaws.services.textract.model StartExpenseAnalysisRequest])
#_(import '[com.amazonaws.services.textract.model GetExpenseAnalysisRequest])
#_(import '[com.amazonaws.services.textract.model DocumentLocation])
(amz/set-client AmazonTextractClient *ns*)

View File

@@ -28,7 +28,6 @@
[(str "container:" (:DockerId container-data))
(str "ip:" (-> container-data :Networks first :IPv4Addresses first))])
(mount/defstate container-tags
:start (get-container-tags)
:stop nil)

View File

@@ -5,14 +5,11 @@
(path [cursor])
(state [cursor]))
(defprotocol ITransact
(-transact! [cursor f]))
(declare to-cursor cursor?)
(deftype ValCursor [value state path]
IDeref
(deref [_]
@@ -26,7 +23,6 @@
(swap! state (if (empty? path) f #(update-in % path f)))
path)))
(deftype MapCursor [value state path]
Counted
(count [_]
@@ -60,7 +56,6 @@
(for [[k v] @this]
[k (to-cursor v state (conj path k) nil)])))
(deftype VecCursor [value state path]
Counted
(count [_]
@@ -98,22 +93,18 @@
(for [[v i] (map vector @this (range))]
(to-cursor v state (conj path i) nil))))
(defn- to-cursor
([v state path value]
(cond
(cursor? v) v
(map? v) (MapCursor. value state path)
(vector? v) (VecCursor. value state path)
:else (ValCursor. value state path)
)))
:else (ValCursor. value state path))))
(defn cursor? [c]
"Returns true if c is a cursor."
(satisfies? ICursor c))
(defn cursor [v]
"Creates cursor from supplied value v. If v is an ordinary
data structure, it is wrapped into atom. If v is an atom,
@@ -123,7 +114,6 @@
(if (instance? Atom v) v (atom v))
[] nil))
(defn synthetic-cursor [v prefix]
(let [internal-cursor (cursor v)]
(reify ICursor
@@ -132,14 +122,12 @@
(state [this]
(state internal-cursor)))))
(defn transact! [cursor f]
"Changes value beneath cursor by passing it to a single-argument
function f. Old value will be passed as function argument. Function
result will be the new value."
(-transact! cursor f))
(defn update! [cursor v]
"Replaces value supplied by cursor with value v."
(-transact! cursor (constantly v)))

View File

@@ -49,8 +49,7 @@
(fn [m k v]
(if (not (nil? v))
(assoc m k v)
m
))
m))
{}
m)]
(if (seq result)
@@ -108,8 +107,7 @@
:db/cardinality :db.cardinality/one
:db/isComponent true
:db.install/_attribute :db.part/db
:db/doc "The vendor's address"}
])
:db/doc "The vendor's address"}])
(def client-schema
[{:db/ident :client/original-id
@@ -151,8 +149,7 @@
:db/doc "Bank accounts for the client"}])
(def address-schema
[
{:db/ident :address/street1
[{:db/ident :address/street1
:db/valueType :db.type/string
:db/cardinality :db.cardinality/one
:db/doc "123 main st"}
@@ -174,8 +171,7 @@
:db/doc "95014"}])
(def contact-schema
[
{:db/ident :contact/name
[{:db/ident :contact/name
:db/valueType :db.type/string
:db/cardinality :db.cardinality/one
:db/doc "John Smith"}
@@ -188,8 +184,6 @@
:db/cardinality :db.cardinality/one
:db/doc "hello@example.com"}])
(def bank-account-schema
[{:db/ident :bank-account/external-id
:db/valueType :db.type/long
@@ -297,7 +291,6 @@
:db/isComponent true
:db/doc "The expense account categories for this invoice"}
{:db/ident :invoice-status/paid}
{:db/ident :invoice-status/unpaid}
{:db/ident :invoice-status/voided}])
@@ -321,8 +314,6 @@
:db/cardinality :db.cardinality/one
:db/doc "The amount that this contributes to"}])
(def payment-schema
[{:db/ident :payment/original-id
:db/valueType :db.type/long
@@ -374,8 +365,7 @@
:db/cardinality :db.cardinality/one
:db/doc "raw data used to generate check pdf"}
;; relations
;; relations
{:db/ident :payment/vendor
:db/valueType :db.type/ref
:db/cardinality :db.cardinality/one
@@ -400,8 +390,7 @@
{:db/ident :payment-type/cash}
{:db/ident :payment-type/check}
{:db/ident :payment-type/debit}
])
{:db/ident :payment-type/debit}])
(def invoice-payment-schema
[{:db/ident :invoice-payment/original-id
@@ -481,8 +470,7 @@
:db/cardinality :db.cardinality/one
:db/doc "The check number that was parsed from the description"}
;; relations
;; relations
{:db/ident :transaction/vendor
:db/valueType :db.type/ref
:db/cardinality :db.cardinality/one
@@ -498,8 +486,7 @@
{:db/ident :transaction/payment
:db/valueType :db.type/ref
:db/cardinality :db.cardinality/one
:db/doc "The payment that this transaction matched to"}
])
:db/doc "The payment that this transaction matched to"}])
(def user-schema
[{:db/ident :user/original-id
@@ -531,12 +518,10 @@
;;enums
{:db/ident :user-role/admin}
{:db/ident :user-role/user}
{:db/ident :user-role/none}
])
{:db/ident :user-role/none}])
(def base-schema
[ address-schema contact-schema vendor-schema client-schema bank-account-schema invoice-schema invoice-expense-account-schema payment-schema invoice-payment-schema transaction-schema user-schema])
[address-schema contact-schema vendor-schema client-schema bank-account-schema invoice-schema invoice-expense-account-schema payment-schema invoice-payment-schema transaction-schema user-schema])
#_{:clj-kondo/ignore [:clojure-lsp/unused-public-var]}
(defn migrate-vendors [_]
@@ -657,7 +642,7 @@
(defn apply-pagination [args results]
{:ids (->> results
(drop (or (:start args) 0))
(take (or (:count args )
(take (or (:count args)
(:per-page args)
default-pagination-size))
(map last))
@@ -695,10 +680,9 @@
:exception e
:level :error
:tx txes)
(throw e)
)))
(throw e))))
(defn pull-many [db read ids ]
(defn pull-many [db read ids]
(->> (dc/q '[:find (pull ?e r)
:in $ [?e ...] r]
db
@@ -706,7 +690,7 @@
read)
(map first)))
(defn pull-many-by-id [db read ids ]
(defn pull-many-by-id [db read ids]
(into {}
(map (fn [[e]]
[(:db/id e) e]))
@@ -734,9 +718,6 @@
(defn pull-ref [db k id]
(:db/id (pull-attr db k id)))
#_(comment
(dc/pull (dc/db conn) '[*] 175921860633685)
@@ -757,9 +738,7 @@
[{:entity/migration-key 17592234924274,
:invoice-expense-account/location nil
:invoice-expense-account/amount 360.0,
:invoice-expense-account/account #:db{:id 92358976759248}}],})
:invoice-expense-account/account #:db{:id 92358976759248}}]})
#_(dc/pull (dc/db conn) auto-ap.datomic.clients 79164837221904)
(upsert-entity (dc/db conn) {:client/name "20Twenty - WG Development LLC",
@@ -864,9 +843,7 @@
:integration-status/last-updated #inst "2022-08-23T13:09:16.082-00:00",
:integration-status/last-attempt #inst "2022-08-23T13:08:47.018-00:00",
:integration-status/state
#:db{:id 101155069755529, :ident :integration-state/success}}})
)
#:db{:id 101155069755529, :ident :integration-state/success}}}))
(defn install-functions []
@(dc/transact conn
@@ -891,7 +868,7 @@
(min (+ backoff-time (rand-int base-timeout)) max-timeout)))
(defn transact-with-backoff
([tx ] (transact-with-backoff tx 0))
([tx] (transact-with-backoff tx 0))
([tx attempt]
(try
@(dc/transact conn tx)
@@ -923,7 +900,6 @@
(into #{}
(map :db/id (:user/clients id [])))))
(defn query2 [query]
(apply dc/q (:query query) (:args query)))

View File

@@ -66,7 +66,7 @@
(and (not [?v :vendor/account-overrides])
[?v :vendor/default-account ?e]))]
(dc/db conn )
(dc/db conn)
vendor-id
client-id
default-read)
@@ -77,7 +77,7 @@
:in $ ?v r
:where [?v :vendor/default-account ?e]]
(dc/db conn )
(dc/db conn)
vendor-id
default-read))))
@@ -111,16 +111,14 @@
:args [(re-pattern (str "(?i)" (:name-like args)))]})
true
(merge-query {:query {:find ['?sort-default '?e ]
(merge-query {:query {:find ['?sort-default '?e]
:where ['[?e :account/name]
'[?e :account/numeric-code ?sort-default]]}}))]
(cond->> (query2 query)
true (apply-sort-3 args)
true (apply-pagination args))))
(defn graphql-results [ids db _]
(let [results (->> (pull-many db default-read ids)
(group-by :db/id))

View File

@@ -14,13 +14,10 @@
(defn <-datomic [x]
(->> x
(map #(update % :bank-account/type :db/ident))
))
(map #(update % :bank-account/type :db/ident))))
(defn get-by-id [id]
(->> [(dc/pull (dc/db conn ) default-read id)]
(->> [(dc/pull (dc/db conn) default-read id)]
(<-datomic)
(first)))

View File

@@ -118,7 +118,6 @@
'[(iol-ion.query/dollars= ?transaction-amount ?amount)]]}
:args [(:amount args)]})
(:status args)
(merge-query {:query {:in ['?status]
:where ['[?e :payment/status ?status]]}
@@ -137,7 +136,6 @@
true
(merge-query {:query {:find ['?sort-default '?e]}})))]
(cond->> (observable-query query)
true (apply-sort-3 (assoc args :default-asc? false))
true (apply-pagination args)))))

View File

@@ -122,8 +122,6 @@
Long/parseLong
(#(hash-map :db/id %)))))
(defn exact-match [identifier]
(when (and identifier (not-empty identifier))
(some-> (solr/query solr/impl "clients"
@@ -170,7 +168,6 @@
matching-ids)
(set (map :db/id (:clients args))))
query (cond-> {:query {:find []
:in ['$]
:where []}
@@ -179,7 +176,6 @@
(merge-query {:query {:in ['[?e ...]]}
:args [(set valid-ids)]})
(:sort args) (add-sorter-fields {"name" ['[?e :client/name ?sort-name]]}
args)
@@ -195,7 +191,6 @@
(map cleanse))]
results))
(defn get-graphql-page [args]
(let [db (dc/db conn)
{ids-to-retrieve :ids matching-count :count} (raw-graphql-ids db args)]

View File

@@ -76,7 +76,6 @@
'[(iol-ion.query/dollars= ?expected-deposit-total ?total)]]}
:args [(:total args)]})
(:start (:date-range args))
(merge-query {:query {:in '[?start-date]
:where ['[?e :expected-deposit/date ?date]

View File

@@ -44,7 +44,6 @@
eas)))
(rename-keys {:invoice-payment/_invoice :invoice/payments})))
(defn raw-graphql-ids
([args]
(raw-graphql-ids (dc/db conn) args))
@@ -63,37 +62,29 @@
valid-clients]}
(cond-> {:query {:find []
:in '[$ [?clients ?start ?end]]
:where '[
[(iol-ion.query/scan-invoices $ ?clients ?start ?end) [[?e _ ?sort-default] ...]]
]}
:where '[[(iol-ion.query/scan-invoices $ ?clients ?start ?end) [[?e _ ?sort-default] ...]]]}
:args [db
[valid-clients
(some-> (:start (:date-range args)) coerce/to-date)
(some-> (:end (:date-range args)) coerce/to-date)]]}
(:client-id args)
(merge-query {:query {:in ['?client-id]
:where ['[?e :invoice/client ?client-id]]}
:args [ (:client-id args)]})
:args [(:client-id args)]})
(:client-code args)
(merge-query {:query {:in ['?client-code]
:where ['[?e :invoice/client ?client-id]
'[?client-id :client/code ?client-code]]}
:args [ (:client-code args)]})
:args [(:client-code args)]})
(:original-id args)
(merge-query {:query {:in ['?original-id]
:where [
'[?e :invoice/client ?c]
:where ['[?e :invoice/client ?c]
'[?c :client/original-id ?original-id]]}
:args [ (cond-> (:original-id args)
(string? (:original-id args)) Long/parseLong )]})
:args [(cond-> (:original-id args)
(string? (:original-id args)) Long/parseLong)]})
(:start (:due-range args)) (merge-query {:query {:in '[?start-due]
:where ['[?e :invoice/due ?due]
@@ -105,25 +96,24 @@
'[(<= ?due ?end-due)]]}
:args [(coerce/to-date (:end (:due-range args)))]})
(:import-status args)
(merge-query {:query {:in ['?import-status]
:where ['[?e :invoice/import-status ?import-status]]}
:args [ (keyword "import-status" (:import-status args))]})
:args [(keyword "import-status" (:import-status args))]})
(:status args)
(merge-query {:query {:in ['?status]
:where ['[?e :invoice/status ?status]]}
:args [ (:status args)]})
:args [(:status args)]})
(:vendor-id args)
(merge-query {:query {:in ['?vendor-id]
:where ['[?e :invoice/vendor ?vendor-id]]}
:args [ (:vendor-id args)]})
:args [(:vendor-id args)]})
(:account-id args)
(merge-query {:query {:in ['?account-id]
:where ['[?e :invoice/expense-accounts ?iea ?]
'[?iea :invoice-expense-account/account ?account-id]]}
:args [ (:account-id args)]})
:args [(:account-id args)]})
(:amount-gte args)
(merge-query {:query {:in ['?amount-gte]
@@ -151,7 +141,7 @@
(:unresolved args)
(merge-query {:query {:in []
:where ['(or-join [?e]
(not [?e :invoice/expense-accounts ])
(not [?e :invoice/expense-accounts])
(and [?e :invoice/expense-accounts ?ea]
(not [?ea :invoice-expense-account/account])))]}
:args []})
@@ -176,12 +166,11 @@
"outstanding-balance" ['[?e :invoice/outstanding-balance ?sort-outstanding-balance]]}
args)
true
(merge-query {:query {:find ['?sort-default '?e ]}}) ))]
(merge-query {:query {:find ['?sort-default '?e]}})))]
(->> (observable-query query)
(apply-sort-3 args)
(apply-pagination args)))))
(defn graphql-results [ids db _]
(let [results (->> (pull-many db default-read ids)
(group-by :db/id))
@@ -210,8 +199,7 @@
(->>
(dc/q {:find ['?id '?o]
:in ['$ '[?id ...]]
:where ['[?id :invoice/total ?o]]
}
:where ['[?id :invoice/total ?o]]}
(dc/db conn)
ids)
(map last)
@@ -226,7 +214,6 @@
outstanding (sum-outstanding ids-to-retrieve)
total-amount (sum-total-amount ids-to-retrieve)]
[(->> (graphql-results ids-to-retrieve db args))
matching-count
outstanding
@@ -239,9 +226,7 @@
(defn get-multi [ids]
(map <-datomic
(pull-many (dc/db conn) default-read ids )))
(pull-many (dc/db conn) default-read ids)))
(defn find-conflicting [{:keys [:invoice/invoice-number :invoice/vendor :invoice/client :db/id]}]
@@ -257,26 +242,23 @@
(map first)
(map <-datomic)))
(defn get-existing-set []
(let [vendored-results (set (dc/q {:find ['?vendor '?client '?invoice-number]
:in ['$]
:where '[[?e :invoice/invoice-number ?invoice-number]
[?e :invoice/vendor ?vendor]
[?e :invoice/client ?client]
(not [?e :invoice/status :invoice-status/voided])
]}
(not [?e :invoice/status :invoice-status/voided])]}
(dc/db conn)))
vendorless-results (->> (dc/q {:find ['?client '?invoice-number]
:in ['$]
:where '[[?e :invoice/invoice-number ?invoice-number]
(not [?e :invoice/vendor])
[?e :invoice/client ?client]
(not [?e :invoice/status :invoice-status/voided])
]}
(not [?e :invoice/status :invoice-status/voided])]}
(dc/db conn))
(mapv (fn [[client invoice-number]]
[nil client invoice-number]) )
[nil client invoice-number]))
set)]
(into vendored-results vendorless-results)))
@@ -317,7 +299,7 @@
client-id))))
[schedule-payment-dom] (map first (dc/q '[:find ?dom
:in $ ?v ?c
:where [?v :vendor/schedule-payment-dom ?sp ]
:where [?v :vendor/schedule-payment-dom ?sp]
[?sp :vendor-schedule-payment-dom/client ?c]
[?sp :vendor-schedule-payment-dom/dom ?dom]]
db

View File

@@ -35,7 +35,7 @@
(some-> (:end (:date-range args)) coerce/to-date)]]}
(:only-external args)
(merge-query {:query {:where ['(not [?e :journal-entry/original-entity ])]}})
(merge-query {:query {:where ['(not [?e :journal-entry/original-entity])]}})
(seq (:external-id-like args))
(merge-query {:query {:in ['?external-id-like]
@@ -53,7 +53,6 @@
:where ['[?e :journal-entry/vendor ?vendor-id]]}
:args [(:vendor-id args)]})
(or (seq (:numeric-code args))
(:bank-account-id args)
(not-empty (:location args)))
@@ -70,7 +69,6 @@
:args [(vec (for [{:keys [from to]} (:numeric-code args)]
[(or from 0) (or to 99999)]))]})
(:amount-gte args)
(merge-query {:query {:in ['?amount-gte]
:where ['[?e :journal-entry/amount ?a]

View File

@@ -43,8 +43,7 @@
:sales-order/source,
:sales-order/reference-link,
{:sales-order/client [:client/name :db/id :client/code]
:sales-order/charges [
:charge/type-name,
:sales-order/charges [:charge/type-name,
:charge/total,
:charge/tax,
:charge/tip,
@@ -63,7 +62,6 @@
(set/intersection #{(:client-id args)}
visible-clients)
(:client-code args)
(set/intersection #{(pull-id db [:client/code (:client-code args)])}
visible-clients)
@@ -79,7 +77,7 @@
:where '[[(iol-ion.query/scan-sales-orders $ ?clients ?start-date ?end-date) [[?e _ ?sort-default] ...]]]}
:args [db [selected-clients
(some-> (:start (:date-range args)) c/to-date)
(some-> (:end (:date-range args)) c/to-date )]]}
(some-> (:end (:date-range args)) c/to-date)]]}
(:sort args) (add-sorter-fields-2 {"client" ['[?e :sales-order/client ?c]
'[?c :client/name ?sort-client]]

View File

@@ -78,7 +78,6 @@
(merge-query {:query {:find ['?e]
:where ['[?e :transaction-rule/transaction-approval-status]]}}))]
(cond->> (query2 query)
true (apply-sort-3 args)
true (apply-pagination args))))
@@ -105,7 +104,7 @@
(defn get-all []
(mapv first
(dc/q {:find [(list 'pull '?e default-read )]
(dc/q {:find [(list 'pull '?e default-read)]
:in ['$]
:where ['[?e :transaction-rule/transaction-approval-status]]}
(dc/db conn))))

View File

@@ -37,7 +37,6 @@
(map first)
set)))
(defn raw-graphql-ids
([args] (raw-graphql-ids (dc/db conn) args))
([db args]
@@ -87,7 +86,6 @@
:where ['[?e :transaction/vendor ?vendor-id]]}
:args [(:vendor-id args)]})
(:amount-gte args)
(merge-query {:query {:in ['?amount-gte]
:where ['[?e :transaction/amount ?a]

View File

@@ -4,7 +4,7 @@
[datomic.api :as dc]
[datomic.api :as d]))
(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 [:find '?e
:in '$
:where '[?e :user/provider]]

View File

@@ -18,7 +18,7 @@
(:vendor/legal-entity-tin-type a) (update :vendor/legal-entity-tin-type :db/ident)
(:vendor/legal-entity-1099-type a) (update :vendor/legal-entity-1099-type :db/ident)
true (assoc :usage (:vendor-usage/_vendor a))
true (dissoc :vendor-usage/_vendor )))
true (dissoc :vendor-usage/_vendor)))
(defn cleanse [id vendor]
(let [clients (if-let [clients (limited-clients id)]
@@ -50,7 +50,6 @@
:vendor/plaid-merchant [:db/id :plaid-merchant/name]
:vendor-usage/_vendor [:vendor-usage/client :vendor-usage/count]}])
(defn raw-graphql-ids [db args]
(let [query (cond-> {:query {:find []
:in ['$]
@@ -70,7 +69,6 @@
(merge-query {:query {:find ['?e]
:where ['[?e :vendor/name]]}}))]
(cond->> (query2 query)
true (apply-sort-3 args)
true (apply-pagination args))))
@@ -86,9 +84,7 @@
(update v :usage (fn [usages]
(->> usages
(map (fn [u] {:client-id (:db/id (:vendor-usage/client u))
:count (:vendor-usage/count u)}))))))
))
:count (:vendor-usage/count u)}))))))))
(defn graphql-results [ids db args]
(let [results (->> (pull-many db default-read ids)
@@ -104,9 +100,7 @@
(let [db (dc/db conn)
{ids-to-retrieve :ids matching-count :count} (raw-graphql-ids db args)]
[(->> (graphql-results ids-to-retrieve db args))
matching-count])
)
matching-count]))
(defn get-graphql-by-id [args id]
(->> (dc/q {:find [(list 'pull '?e default-read)]
@@ -139,7 +133,6 @@
(map <-datomic)
(first)))
(defn terms-for-client-id [vendor client-id]
(or
(->>

View File

@@ -20,16 +20,15 @@
:body (json/write-str {"query" (v/graphql-query q)})
:as :json})
:body
:data
))
:data))
(defn get-caterers [integration]
(:caterers (query integration {:venia/queries [{:query/data
[:caterers [:name :uuid [:address [:name :street]]]]}]} )))
[:caterers [:name :uuid [:address [:name :street]]]]}]})))
(defn get-subscriptions [integration]
(->> (query integration {:venia/queries [{:query/data
[:subscribers [:id [:subscriptions [:parentId :parentEntity :eventEntity :eventKey]] ]]}]} )
[:subscribers [:id [:subscriptions [:parentId :parentEntity :eventEntity :eventKey]]]]}]})
:subscribers
first
:subscriptions))
@@ -94,7 +93,6 @@
:eventKey 'cancelled}}
[[:subscription [:parentId :parentEntity :eventEntity :eventKey]]]]]})))))
#_{:clj-kondo/ignore [:clojure-lsp/unused-public-var]}
(defn upsert-ezcater
([] (upsert-ezcater (get-integrations)))
@@ -121,7 +119,6 @@
{:client/_ezcater-locations [:client/code]}]}]
[:ezcater-caterer/uuid caterer-uuid]))
(defn round-carry-cents [f]
(with-precision 2 (double (.setScale (bigdec f) 2 java.math.RoundingMode/HALF_UP))))
@@ -139,7 +136,7 @@
(* commision%
0.01M
(+
(-> order :totals :subTotal :subunits )
(-> order :totals :subTotal :subunits)
(reduce +
0
(map (comp :subunits :cost) (:feesAndDiscounts (:catererCart order)))))))))
@@ -148,8 +145,8 @@
(round-carry-cents
(* 0.000299M
(+
(-> order :totals :subTotal :subunits )
(-> order :totals :salesTax :subunits )
(-> order :totals :subTotal :subunits)
(-> order :totals :salesTax :subunits)
(reduce +
0
(map (comp :subunits :cost) (:feesAndDiscounts (:catererCart order))))))))
@@ -157,7 +154,7 @@
(defn order->sales-order [{{:keys [timestamp]} :event {:keys [orderItems]} :catererCart :keys [client-code client-location uuid] :as order}]
(let [adjustment (round-carry-cents (- (+ (-> order :totals :subTotal :subunits (* 0.01))
(-> order :totals :salesTax :subunits (* 0.01)))
(-> order :catererCart :totals :catererTotalDue )
(-> order :catererCart :totals :catererTotalDue)
(commision order)
(ccp-fee order)))
service-charge (+ (commision order) (ccp-fee order))
@@ -168,7 +165,7 @@
:external-id (str "ezcater/order/" client-code "-" client-location "-" uuid)
:client [:client/code client-code]
:location client-location
:reference-link (str (url/url "https://ezmanage.ezcater.com/orders/" uuid ))
:reference-link (str (url/url "https://ezmanage.ezcater.com/orders/" uuid))
:line-items [#:order-line-item
{:external-id (str "ezcater/order/" client-code "-" client-location "-" uuid "-" 0)
:item-name "EZCater Catering"
@@ -200,7 +197,6 @@
:returns 0.0
:vendor :vendor/ccp-ezcater}))
(defn get-by-id [integration id]
(query
integration
@@ -231,27 +227,20 @@
[:currency
:subunits]]]]]]
[:totals [[:customerTotalDue
[
:currency
:subunits
]]
[:currency
:subunits]]
[:pointOfSaleIntegrationFee
[
:currency
:subunits
]]
[:currency
:subunits]]
[:tip
[:currency
:subunits]]
[:salesTax
[
:currency
:subunits
]]
[:currency
:subunits]]
[:salesTaxRemittance
[:currency
:subunits
]]
:subunits]]
[:subTotal
[:currency
:subunits]]]]]]]}))

View File

@@ -34,8 +34,7 @@
(clojure.lang IPersistentMap)))
(def integreat-schema
{
:scalars {:id {:parse #(cond (number? %)
{:scalars {:id {:parse #(cond (number? %)
%
%
@@ -86,8 +85,7 @@
(str %)
%)}}
:objects
{
:message
{:message
{:fields {:message {:type 'String}}}
:search_result
@@ -128,7 +126,6 @@
:email {:type 'String}
:phone {:type 'String}}}
:address
{:fields {:id {:type :id}
:street1 {:type 'String}
@@ -184,7 +181,6 @@
:legal_entity_tin_type {:type :tin_type}
:legal_entity_1099_type {:type :type_1099}}}
:reminder
{:fields {:id {:type 'Int}
:email {:type 'String}
@@ -222,8 +218,6 @@
:accounts {:type '(list :percentage_account)}
:transaction_approval_status {:type :transaction_approval_status}}}
:user
{:fields {:id {:type :id}
:name {:type 'String}
@@ -264,18 +258,12 @@
:start {:type 'Int}
:end {:type 'Int}}}
:transaction_rule_page {:fields {:transaction_rules {:type '(list :transaction_rule)}
:count {:type 'Int}
:total {:type 'Int}
:start {:type 'Int}
:end {:type 'Int}}}
:vendor_page {:fields {:vendors {:type '(list :vendor)}
:count {:type 'Int}
:total {:type 'Int}
@@ -321,7 +309,6 @@
:args {:transaction_id {:type :id}}
:resolve :get-transaction-rule-matches}
:test_transaction_rule {:type '(list :transaction)
:args {:transaction_rule {:type :edit_transaction_rule}}
:resolve :test-transaction-rule}
@@ -338,7 +325,6 @@
:args {:client_id {:type :id}}
:resolve :get-cash-flow}
:all_accounts {:type '(list :account)
:args {}
:resolve :get-all-accounts}
@@ -353,10 +339,6 @@
:vendor_id {:type :id}}
:resolve :search-account}
:yodlee_merchants {:type '(list :yodlee_merchant)
:args {}
:resolve :get-yodlee-merchants}
@@ -376,9 +358,6 @@
:description {:type 'String}}
:resolve :get-transaction-rule-page}
:vendor {:type :vendor_page
:args {:name_like {:type 'String}
:start {:type 'Int}
@@ -395,8 +374,7 @@
:resolve :account-for-vendor}}
:input-objects
{
:sort_item
{:sort_item
{:fields {:sort_key {:type 'String}
:sort_name {:type 'String}
:asc {:type 'Boolean}}}
@@ -495,8 +473,7 @@
:name {:type 'String}
:client_overrides {:type '(list :edit_account_client_override)}}}}
:enums {
:processor {:values [{:enum-value :na}
:enums {:processor {:values [{:enum-value :na}
{:enum-value :doordash}
{:enum-value :koala}
{:enum-value :ezcater}
@@ -533,9 +510,7 @@
{:enum-value :equity}
{:enum-value :revenue}]}}
:mutations
{
:delete_transaction_rule
{:delete_transaction_rule
{:type :id
:args {:transaction_rule_id {:type :id}}
:resolve :mutation/delete-transaction-rule}
@@ -553,9 +528,7 @@
:upsert_transaction_rule
{:type :transaction_rule
:args {:transaction_rule {:type :edit_transaction_rule}}
:resolve :mutation/upsert-transaction-rule}
}})
:resolve :mutation/upsert-transaction-rule}}})
(defn snake->kebab [s]
(str/replace s #"_" "-"))
@@ -581,8 +554,7 @@
node))
m))
(defn get-expense-account-stats [_ {:keys [client_id] } _]
(defn get-expense-account-stats [_ {:keys [client_id]} _]
(let [query (cond-> {:query {:find ['?account '?account-name '(sum ?amount)]
:in ['$]
:where []}
@@ -601,7 +573,7 @@
(for [[account-id account-name total] result]
{:account {:id account-id :name account-name} :total total})))
(defn get-invoice-stats [_ {:keys [client_id] } _]
(defn get-invoice-stats [_ {:keys [client_id]} _]
(let [query (cond-> {:query {:find ['?name '(sum ?outstanding-balance) '(sum ?total)]
:in ['$]
:where []}
@@ -615,7 +587,7 @@
'[?i :invoice/total ?total]
'[?i :invoice/due ?date]
'[(.toInstant ^java.util.Date ?date) ?d2]
'[(.between java.time.temporal.ChronoUnit/DAYS (java.time.Instant/now) ?d2 ) ?d3]
'[(.between java.time.temporal.ChronoUnit/DAYS (java.time.Instant/now) ?d2) ?d3]
'(or-join [?d3 ?name]
(and [(<= ?d3 0)]
[(ground :due) ?name])
@@ -629,7 +601,7 @@
(group-by first))]
(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)
outstanding-balance (or outstanding-balance 0)
total (or total 0)]]
{:name name :unpaid outstanding-balance :paid (if (= :due id)
@@ -652,7 +624,7 @@
(defn get-cash-flow [_ {:keys [client_id]} _]
(when client_id
(let [{:client/keys [week-a-credits week-a-debits week-b-credits week-b-debits forecasted-transactions ]} (dc/pull (dc/db conn) '[*] client_id)
(let [{:client/keys [week-a-credits week-a-debits week-b-credits week-b-debits forecasted-transactions]} (dc/pull (dc/db conn) '[*] client_id)
total-cash (reduce
(fn [total [credit debit]]
(- (+ total credit)
@@ -736,12 +708,10 @@
(take (* 7 4) (time/day-of-week-seq 1)))
(filter #(< (:amount %) 0) forecasted-transactions))})))
(def schema
(-> integreat-schema
(attach-tracing-resolvers
{
:get-all-accounts gq-accounts/get-all-graphql
{:get-all-accounts gq-accounts/get-all-graphql
:get-transaction-rule-page gq-transaction-rules/get-transaction-rule-page
:get-transaction-rule-matches gq-transaction-rules/get-transaction-rule-matches
:get-expense-account-stats get-expense-account-stats
@@ -772,8 +742,6 @@
gq-sales-orders/attach
schema/compile))
(defn simplify
"Converts all ordered maps nested within the map into standard hash maps, and
sequences into vectors, which makes for easier constants in the tests, and eliminates ordering problems."
@@ -805,7 +773,7 @@
(query id q nil))
([id q v]
(statsd/increment "query.graphql.count" {:tags #{(str "query:" (query-name q))}})
(statsd/time! [(str "query.graphql.time" ) {:tags #{(str "query:" (query-name q))}}]
(statsd/time! [(str "query.graphql.time") {:tags #{(str "query:" (query-name q))}}]
(mu/with-context {:query-name (query-name q) :user id :query q}
(mu/trace ::executing-query
[]

View File

@@ -18,7 +18,6 @@
[iol-ion.tx :refer [random-tempid]]
[com.brunobonacci.mulog :as mu]))
(defn get-all-graphql [context args _]
(assert-admin (:id context))
(let [args (assoc args :id (:id context))

View File

@@ -97,7 +97,6 @@
[:line {:line-width 0.15 :color [50 50 50]}]]
[:cell {:colspan 3}]]
[[:cell {:size 9 :leading 11.5} "\n\n\n\n\nMEMO"]
[:cell {:colspan 5 :leading 11.5} (split-memo memo)
[:line {:line-width 0.15 :color [50 50 50]}]]
@@ -186,8 +185,6 @@
:payment/pdf-data
(edn/read-string)
make-check-pdf)]
(s3/put-object :bucket-name (:data-bucket env)
:key (:payment/s3-key check)
@@ -277,7 +274,6 @@
(conj payment)
(into (invoice-payments invoices invoice-amounts)))))
(defmethod invoices->entities :payment-type/debit [invoices vendor client bank-account type index invoice-amounts date]
(when (<= (->> invoices
(map (comp invoice-amounts :db/id))
@@ -297,7 +293,6 @@
(conj payment)
(into (invoice-payments invoices invoice-amounts)))))
(defmethod invoices->entities :payment-type/balance-credit [invoices invoice-amounts]
(when (<= (->> invoices
(map (comp invoice-amounts :db/id))
@@ -488,7 +483,6 @@
{:s3-url nil
:invoices (d-invoices/get-multi (map :invoice_id (:invoice_payments args)))})))
(defn void-payment [context {id :payment_id} _]
(let [check (d-checks/get-by-id id)]
(assert (or (= :payment-status/pending (:payment/status check))
@@ -549,7 +543,6 @@
:invoice-status/unpaid)}]]))))))))
id))
(defn void-payments [context args _]
(assert-admin (:id context))
(let [args (assoc args :clients (:clients context))
@@ -607,7 +600,6 @@
0.001))
invoices)
total-to-pay (reduce + 0 (map :invoice/outstanding-balance invoices-to-be-paid))
_ (when (<= total-to-pay 0.001)
(assert-failure "You must select invoices that need to be paid."))
@@ -637,8 +629,6 @@
[total-to-pay []])))
(into {}))
vendor-id (:db/id (:invoice/vendor (first invoices)))
payment {:db/id (str vendor-id)
:payment/amount total-to-pay
@@ -751,7 +741,6 @@
{:enum-value :pending}
{:enum-value :cleared}]}})
(def resolvers
{:get-potential-payments get-potential-payments
:get-payment-page get-payment-page

View File

@@ -47,13 +47,6 @@
bank-accounts))))))]
(result->page clients clients-count :clients (:filters args))))
(def objects
{:location_match
{:fields {:location {:type 'String}
@@ -109,8 +102,6 @@
:start {:type 'Int}
:end {:type 'Int}}}
:bank_account
{:fields {:id {:type :id}
:integration_status {:type :integration_status}
@@ -139,9 +130,7 @@
:forecasted_transaction {:fields {:identifier {:type 'String}
:id {:type :id}
:day_of_month {:type 'Int}
:amount {:type :money}}}
})
:amount {:type :money}}}})
(def queries
{:client {:type '(list :client)
@@ -158,12 +147,12 @@
{})
(def input-objects
{ :client_filters
{:client_filters
{:fields {:code {:type 'String}
:name_like {:type 'String}
:start {:type 'Int}
:per_page {:type 'Int}
:sort {:type '(list :sort_item)}}} })
:sort {:type '(list :sort_item)}}}})
(def enums
{:bank_account_type {:values [{:enum-value :check}
@@ -173,8 +162,7 @@
(def resolvers
{:get-client get-client
:get-admin-client get-admin-client
:get-client-page get-client-page })
:get-client-page get-client-page})
(defn attach [schema]
(->

View File

@@ -17,7 +17,6 @@
{:name name
:id id}))
(def objects
{:ezcater_caterer {:fields {:name {:type 'String}
:id {:type :id}}}})

View File

@@ -40,7 +40,6 @@
(merge-query {:query {:find ['?e]
:where ['[?e :import-batch/date]]}}))]
(cond->> (query2 query)
true (apply-sort-3 args)
true (apply-pagination args))))
@@ -66,7 +65,6 @@
(map #(update % :import-batch/date coerce/to-date-time)))
matching-count :data args)))
(defn attach [schema]
(->
(merge-with merge schema
@@ -83,9 +81,7 @@
:count {:type 'Int}
:total {:type 'Int}
:start {:type 'Int}
:end {:type 'Int}}}
}
:end {:type 'Int}}}}
:queries {:import_batch_page {:type :import_batch_page
:args {:filters {:type :import_batch_filters}}

View File

@@ -174,8 +174,6 @@
(let [error (str "Expense account total (" expense-account-total ") does not equal invoice total (" total ")")]
(throw (ex-info error {:validation-error error}))))))
(defn add-invoice [context {{:keys [expense_accounts client_id vendor_id] :as in} :invoice} _]
(assert-no-conflicting in)
(assert-can-see-client (:id context) client_id)
@@ -193,8 +191,6 @@
(when-not ((set (map :db/id (:client/bank-accounts (d-clients/get-by-id client-id)))) bank-account-id)
(throw (ex-info (str "Bank account does not belong to client") {:validation-error "Bank account does not belong to client."}))))
(defn add-and-print-invoice [context {{:keys [total client_id vendor_id] :as in} :invoice bank-account-id :bank_account_id type :type} _]
(mu/trace ::validating-invoice [:invoice in]
(do
@@ -261,7 +257,6 @@
(-> (d-invoices/get-by-id id) (->graphql (:id context)))))
(defn get-ids-matching-filters [args]
(let [ids (some-> args
:filters
@@ -448,8 +443,6 @@
[])]
accounts)))
(defn bulk-change-invoices [context args _]
(assert-admin (:id context))
(when-not (:client_id args)

View File

@@ -55,10 +55,8 @@
(let [args (assoc args :id (:id context))
[journal-entries journal-entries-count] (l/get-graphql (assoc (<-graphql (:filters args))
:per-page Integer/MAX_VALUE
:clients (:clients context)))
:clients (:clients context)))]
]
{:csv_content_b64 (Base64/encodeBase64String
(.getBytes
(with-open [w (java.io.StringWriter.)]
@@ -83,22 +81,19 @@
(-> li :journal-entry-line/account :bank-account/numeric-code))
(or (-> li :journal-entry-line/account :account/name)
(-> li :journal-entry-line/account :bank-account/name))
(some-> account-type name )
(some-> account-type name)
(-> li :journal-entry-line/debit)
(-> li :journal-entry-line/credit)
(if (#{:account-type/asset
:account-type/dividend
:account-type/expense} account-type)
(- (or (-> li :journal-entry-line/debit) 0.0) (or (-> li :journal-entry-line/credit) 0.0))
(- (or (-> li :journal-entry-line/credit) 0.0) (or (-> li :journal-entry-line/debit) 0.0)))
(- (or (-> li :journal-entry-line/credit) 0.0) (or (-> li :journal-entry-line/debit) 0.0)))]))
]))
(:journal-entry/line-items j))
))))
(:journal-entry/line-items j))))))
:quote? (constantly true))
(.toString w))))}))
(defn roll-up-until
([lookup-account all-ledger-entries end-date]
(roll-up-until lookup-account all-ledger-entries end-date nil))
@@ -115,8 +110,7 @@
(-> acc
(update-in [[location account] :debit] (fnil + 0.0) debit)
(update-in [[location account] :credit] (fnil + 0.0) credit)
(update-in [[location account] :count] (fnil + 0) 1))
)
(update-in [[location account] :count] (fnil + 0) 1)))
{})
(reduce-kv
(fn [acc [location account-id] {:keys [debit credit count]}]
@@ -152,9 +146,9 @@
(or [?b :bank-account/include-in-reports true]
(not [?b :bank-account/include-in-reports])))
(not [?i :transaction/bank-account])))
(not [?e :journal-entry/original-entity ]))
(not [?e :journal-entry/original-entity]))
[(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/location "") ?location]]}
(dc/db conn) client-id)
@@ -182,16 +176,15 @@
(alog/info ::balance-sheet :params args)
(cond-> {:balance-sheet-accounts (mapcat
#(roll-up-until (lookup-account %) (all-ledger-entries %) end-date )
client-ids)
}
#(roll-up-until (lookup-account %) (all-ledger-entries %) end-date)
client-ids)}
(:include_comparison args) (assoc :comparable-balance-sheet-accounts (mapcat
#(roll-up-until (lookup-account %) (all-ledger-entries %) comparable-date )
#(roll-up-until (lookup-account %) (all-ledger-entries %) comparable-date)
client-ids))
true ->graphql)))
(defn get-profit-and-loss-raw [client-ids periods]
(let [ all-ledger-entries (->> client-ids
(let [all-ledger-entries (->> client-ids
(map (fn [client-id]
[client-id (full-ledger-for-client client-id)]))
(into {}))
@@ -203,7 +196,7 @@
(->> periods
(mapv (fn [{:keys [start end]}]
{:accounts (mapcat
#(roll-up-until (lookup-account %) (all-ledger-entries %) (coerce/to-date end) (coerce/to-date start) )
#(roll-up-until (lookup-account %) (all-ledger-entries %) (coerce/to-date end) (coerce/to-date start))
client-ids)})))})))
(defn get-profit-and-loss [context args _]
@@ -216,12 +209,9 @@
(assert-can-see-client (:id context) client-id))
_ (when (and (:include_deltas args)
(:column_per_location args))
(throw (ex-info "Please select one of 'Include deltas' or 'Column per location'" {:validation-error "Please select one of 'Include deltas' or 'Column per location'"}))) ]
(throw (ex-info "Please select one of 'Include deltas' or 'Column per location'" {:validation-error "Please select one of 'Include deltas' or 'Column per location'"})))]
(get-profit-and-loss-raw client-ids (:periods args))))
;; profit and loss based off of index
#_(defn get-profit-and-loss [context args _]
(let [client-id (:client_id args)
@@ -296,8 +286,7 @@
:debits 0
:credits 0
:amount (- (or (:journal-entry-line/running-balance end-point) 0.0)
(or (:journal-entry-line/running-balance start-point) 0.0))
}
(or (:journal-entry-line/running-balance start-point) 0.0))}
((lookup-account c) a))])))
all-used-account-locations)}))))})))
@@ -320,7 +309,6 @@
(->graphql result)))
(defn assoc-error [f]
(fn [entry]
(try
@@ -443,7 +431,7 @@
(assoc-error (fn [entry]
(let [vendor (all-vendors (:vendor_name entry))]
(when-not (client-locked-lookup (:client_code entry))
(throw (ex-info (str "Client '" (:client_code entry )"' not found.") {:status :error}) ))
(throw (ex-info (str "Client '" (:client_code entry) "' not found.") {:status :error})))
(when-not vendor
(throw (ex-info (str "Vendor '" (:vendor_name entry) "' not found.") {:status :error})))
(when-not (re-find #"\d{1,2}/\d{1,2}/\d{4}" (:date entry))
@@ -542,19 +530,17 @@
retraction (mapv (fn [x] [:db/retractEntity [:journal-entry/external-id (:external_id x)]])
success)
ignore-retraction (->> ignored
(map :external_id )
(map :external_id)
(dc/q '[:find ?je
:in $ [?ei ...]
:where [?je :journal-entry/external-id ?ei]]
(dc/db conn)
)
(dc/db conn))
(map first)
(map (fn [je] [:db/retractEntity je])))]
(alog/info ::manual-import
:errors (count errors)
:sample (take 3 errors))
(mu/trace ::retraction-tx
[:count (count retraction)]
(audit-transact-batch retraction (:id context)))
@@ -582,7 +568,6 @@
:errors (map (fn [x] {:external_id (:external_id x)
:error (:error x)}) errors)}))
(defn get-journal-detail-report [context input _]
(let [category-totals (atom {})
base-categories (into []
@@ -597,8 +582,8 @@
:clients [{:db/id client-id}])
{:filters {:location location
:date_range (:date_range input)
:from_numeric_code (l-reports/min-numeric-code category )
:to_numeric_code (l-reports/max-numeric-code category )
:from_numeric_code (l-reports/min-numeric-code category)
:to_numeric_code (l-reports/max-numeric-code category)
:per_page Integer/MAX_VALUE}}
nil)
:journal_entries
@@ -608,9 +593,8 @@
(when-let [account (account-lookup (:id (:account jel)))]
(and
(l-reports/account-belongs-in-category? (:numeric_code account) category)
(= location (:location jel)))))
)
(map (fn [jel ]
(= location (:location jel))))))
(map (fn [jel]
{:date (:date je)
:debit (:debit jel)
:credit (:credit jel)
@@ -621,7 +605,7 @@
(into []))
_ (swap! category-totals assoc-in [client-id location category]
(- (or (reduce + 0.0 (map #(or (:credit %) 0.0) all-journal-entries)) 0.0)
(or (reduce + 0.0 (map #(or (:debit %) 0.0) all-journal-entries)) 0.0)) )
(or (reduce + 0.0 (map #(or (:debit %) 0.0) all-journal-entries)) 0.0)))
journal-entries-by-account (group-by #(account-lookup (get-in % [:account :id])) all-journal-entries)]
[account journal-entries] (conj (vec journal-entries-by-account) [nil all-journal-entries])
:let [journal-entries (first (reduce
@@ -675,15 +659,12 @@
line))}]
result))
(defn journal-detail-report-pdf [context args value]
(let [data (get-journal-detail-report context args value)
result (print-journal-detail-report (:id context) args data)]
(->graphql result)))
(def objects
{:balance_sheet_account
{:fields {:id {:type 'String}
@@ -881,8 +862,7 @@
:amount {:type :money}
:note {:type 'String}
:cleared_against {:type 'String}
:line_items {:type '(list :import_ledger_line_item)}}}
})
:line_items {:type '(list :import_ledger_line_item)}}}})
(def enums
{:ledger_category {:values [{:enum-value :sales}
@@ -892,7 +872,6 @@
{:enum-value :fixed_overhead}
{:enum-value :ownership_controllable}]}})
(def resolvers
{:get-ledger-page get-ledger-page
:get-balance-sheet get-balance-sheet

View File

@@ -21,13 +21,11 @@
:name (first name)}))
[]))
(defn attach [schema]
(->
(merge-with merge schema
{:objects {:plaid_link_result
{:fields {:token {:type 'String}} }
{:fields {:token {:type 'String}}}
:plaid_item
{:fields {:external_id {:type 'String}

View File

@@ -1,6 +1,6 @@
(ns auto-ap.graphql.sales-orders
(:require [auto-ap.datomic.sales-orders :as d-sales-orders2]
[auto-ap.graphql.utils :refer [->graphql <-graphql result->page assert-admin] ]
[auto-ap.graphql.utils :refer [->graphql <-graphql result->page assert-admin]]
[com.walmartlabs.lacinia.util :refer [attach-resolvers]]
[auto-ap.graphql.utils :refer [attach-tracing-resolvers]]))
@@ -17,7 +17,6 @@
->graphql
(first (d-sales-orders2/get-graphql (assoc (<-graphql args) :count Integer/MAX_VALUE)))))
(def objects
{:sales_order_page
{:fields {:sales_orders {:type '(list :sales_order)}
@@ -93,8 +92,7 @@
(def resolvers
{:get-all-sales-orders get-all-sales-orders
:get-sales-order-page get-sales-orders-page
})
:get-sales-order-page get-sales-orders-page})
(defn attach [schema]
(->

View File

@@ -29,9 +29,8 @@
(defn get-transaction-rule-matches [context args _]
(if (= "admin" (:user/role (:id context)))
(let [transaction (update (d-transactions/get-by-id (:transaction_id args)) :transaction/date c/to-date)
all-rules (tr/get-all-for-client (:db/id (:transaction/client transaction)))
all-rules (tr/get-all-for-client (:db/id (:transaction/client transaction)))]
]
(mu/log ::counted
:count (count all-rules))
(doto (map ->graphql (rm/get-matching-rules transaction all-rules)) (#(println (count %)))))
@@ -43,7 +42,7 @@
:account account_id
:location location})
(defn delete-transaction-rule [context {:keys [transaction_rule_id ]} _]
(defn delete-transaction-rule [context {:keys [transaction_rule_id]} _]
(assert-admin (:id context))
(let [existing-transaction-rule (tr/get-by-id transaction_rule_id)]
(when-not (:transaction-rule/description existing-transaction-rule)
@@ -68,17 +67,16 @@
(throw (ex-info error {:validation-error error}))))
_ (doseq [a accounts
:let [{:keys [:account/location :account/name]} (dc/pull (dc/db conn) [:account/location :account/name] (:account_id a))
client (dc/pull (dc/db conn) [:client/locations] client_id)
]]
client (dc/pull (dc/db conn) [:client/locations] client_id)]]
(when (and location (not= location (:location a)))
(let [err (str "Account " name " uses location " (:location a) ", but is supposed to be " location)]
(throw (ex-info err {:validation-error err}) )))
(throw (ex-info err {:validation-error err}))))
(when (and (not location)
(not (get (into #{"Shared"} (:client/locations client))
(:location a))))
(let [err (str "Account " name " uses location " (:location a) ", but doesn't belong to the client.")]
(throw (ex-info err {:validation-error err}) ))))
(throw (ex-info err {:validation-error err})))))
rule-id (if id
id
"transaction-rule")
@@ -100,7 +98,6 @@
(keyword "transaction-approval-status"))
:transaction-rule/accounts (map transaction-rule-account->entity accounts)}]]
transaction-result (audit-transact transaction (:id context))]
(-> (tr/get-by-id (or (-> transaction-result :tempids (get "transaction-rule"))
id))
@@ -110,9 +107,8 @@
(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]
:transaction/bank-account [:bank-account/name]
:transaction/payment [:db/id]}
])]
:in ['$ ]
:transaction/payment [:db/id]}])]
:in ['$]
:where []}
:args [(dc/db conn)]}
description
@@ -170,7 +166,6 @@
:where ['[?e :transaction/client ?client-id]]}
:args [(:db/id client)]})
(not include-coded?)
(merge-query {:query {:where ['[or [?e :transaction/approval-status :transaction-approval-status/unapproved]
[(missing? $ ?e :transaction/approval-status)]]]}})
@@ -200,7 +195,6 @@
:yodlee-merchant (when yodlee_merchant_id {:db/id yodlee_merchant_id})}
true 15))
(defn run-transaction-rule [{:keys [id]} {:keys [transaction_rule_id count]} _]
(assert-admin id)
(-test-transaction-rule id (tr/get-by-id transaction_rule_id) false count))

View File

@@ -73,7 +73,7 @@
(<-graphql)
(update :approval-status enum->keyword "transaction-approval-status")
(assoc :per-page Integer/MAX_VALUE)
(d-transactions/raw-graphql-ids )
(d-transactions/raw-graphql-ids)
:ids)
specific-ids (d-transactions/filter-ids (seq (:ids args)))]
(if (seq (:ids args))
@@ -100,8 +100,7 @@
(alog/info ::bulk-change-status
:count (count all-ids)
:sample (take 3 all-ids)
:status (:status args)
)
:status (:status args))
(audit-transact-batch
(->> all-ids
(mapv (fn [t]
@@ -109,7 +108,7 @@
:transaction/approval-status (enum->keyword (:status args) "transaction-approval-status")}])))
(: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)) ".")}))
;; TODO very similar to rule-matching
(defn maybe-code-accounts [transaction account-rules valid-locations]
@@ -154,7 +153,7 @@
{:validation-error "Client is required"})))
(let [args (assoc args :clients (:clients context) :id (:id context))
client->locations (->> (:clients context)
(map :db/id )
(map :db/id)
(dc/q
'[:find (pull ?e [:db/id :client/locations])
:in $ [?e ...]]
@@ -180,13 +179,13 @@
(:account_id a))]]
(when (and location (not= location (:location a)))
(let [err (str "Account " name " uses location " (:location a) ", but is supposed to be " location)]
(throw (ex-info err {:validation-error err}) )))
(throw (ex-info err {:validation-error err}))))
(doseq [[_ locations] client->locations]
(when (and (not location)
(not (get (into #{"Shared"} locations)
(:location a))))
(let [err (str "Account " name " uses location " (:location a) ", but doesn't belong to the client.")]
(throw (ex-info err {:validation-error err}) )))))
(throw (ex-info err {:validation-error err}))))))
(audit-transact-batch
(map (fn [t]
(let [locations (client->locations (-> t :transaction/client :db/id))]
@@ -200,7 +199,6 @@
(:id context))
{:message (str "Successfully coded " (count all-ids) " transactions.")}))
(defn delete-transactions [context args _]
(let [_ (assert-admin (:id context))
args (assoc args :clients (:clients context))
@@ -242,21 +240,21 @@
(assert-power-user (:id context))
(let [transaction (d-transactions/get-by-id (:transaction_id args))
_ (assert-can-see-client (:id context) (:transaction/client transaction) )
_ (assert-can-see-client (:id context) (:transaction/client transaction))
matches-set (i-transactions/match-transaction-to-unfulfilled-autopayments (:transaction/amount transaction)
(:db/id (:transaction/client transaction)))]
(->graphql (for [matches matches-set]
(for [[_ invoice-id ] matches]
(for [[_ invoice-id] matches]
(d-invoices/get-by-id invoice-id))))))
(defn get-potential-unpaid-invoices-matches [context args _]
(assert-power-user (:id context))
(let [transaction (d-transactions/get-by-id (:transaction_id args))
_ (assert-can-see-client (:id context) (:transaction/client transaction) )
_ (assert-can-see-client (:id context) (:transaction/client transaction))
matches-set (i-transactions/match-transaction-to-unpaid-invoices (:transaction/amount transaction)
(:db/id (:transaction/client transaction)))]
(->graphql (for [matches matches-set]
(for [[_ invoice-id ] matches]
(for [[_ invoice-id] matches]
(d-invoices/get-by-id invoice-id))))))
(defn unlink-transaction [context args _]
@@ -271,13 +269,13 @@
:transaction/vendor
:transaction/accounts
:transaction/client [:db/id]
{:transaction/payment [:payment/date {:payment/status [:db/ident]} :db/id]} ]
{:transaction/payment [:payment/date {:payment/status [:db/ident]} :db/id]}]
transaction-id)
_ (assert-can-see-client (:id context) (:transaction/client transaction) )
_ (assert-can-see-client (:id context) (:transaction/client transaction))
_ (assert-not-locked (:db/id (:transaction/client transaction)) (:transaction/date transaction))
_ (when (:transaction/payment transaction)
(assert-not-locked (:db/id (:transaction/client transaction)) (-> transaction :transaction/payment :payment/date)))
payment (-> transaction :transaction/payment )
payment (-> transaction :transaction/payment)
is-autopay-payment? (some->> (dc/q {:find ['?sp]
:in ['$ '?payment]
:where ['[?ip :invoice-payment/payment ?payment]
@@ -286,8 +284,7 @@
(dc/db conn) (:db/id payment))
seq
(map first)
(every? #(instance? java.util.Date %)))
]
(every? #(instance? java.util.Date %)))]
(alog/info ::unlinking :transaction (pr-str transaction) :autopay is-autopay-payment? :payment (pr-str payment))
@@ -305,7 +302,7 @@
:transaction/location nil
:transaction/accounts nil}]
[:db/retractEntity (:db/id payment) ]]
[:db/retractEntity (:db/id payment)]]
(into (map (fn [[invoice-payment]]
[:db/retractEntity invoice-payment])
@@ -313,7 +310,7 @@
:in ['$ '?p]
:where ['[?ip :invoice-payment/payment ?p]]}
(dc/db conn)
(:db/id payment) ))))
(:db/id payment)))))
(:id context))
(audit-transact
[{:db/id (:db/id payment)
@@ -330,14 +327,12 @@
approval-status->graphql
->graphql)))
(defn transaction-account->entity [{:keys [id account_id amount location]}]
#:transaction-account {:amount amount
:db/id (or id (random-tempid))
:account account_id
:location location})
(defn assert-valid-expense-accounts [accounts]
(doseq [trans-account accounts
:let [account (dc/pull (dc/db conn)
@@ -359,13 +354,12 @@
(throw (ex-info err
{:validation-error err}))))
(when (nil? (:account_id trans-account))
(throw (ex-info "Account is missing account" {:validation-error "Account is missing account"})))))
(defn edit-transaction [context {{:keys [id accounts vendor_id approval_status memo forecast_match]} :transaction} _]
(let [existing-transaction (d-transactions/get-by-id id)
_ (assert-can-see-client (:id context) (:transaction/client existing-transaction) )
_ (assert-can-see-client (:id context) (:transaction/client existing-transaction))
_ (assert-valid-expense-accounts accounts)
_ (assert-not-locked (:db/id (:transaction/client existing-transaction)) (:transaction/date existing-transaction))
account-total (reduce + 0 (map (fn [x] (:amount x)) accounts))
@@ -387,7 +381,7 @@
(let [error (str "Expense account total (" account-total ") does not equal transaction total (" (Math/abs (:transaction/amount existing-transaction)) ")")]
(throw (ex-info error {:validation-error error}))))
(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 (cond-> [[:upsert-transaction {:db/id id
:transaction/vendor vendor_id
@@ -413,8 +407,8 @@
(defn match-transaction [context {:keys [transaction_id payment_id]} _]
(let [transaction (d-transactions/get-by-id transaction_id)
payment (d-checks/get-by-id payment_id)
_ (assert-can-see-client (:id context) (:transaction/client transaction) )
_ (assert-can-see-client (:id context) (:payment/client payment) )
_ (assert-can-see-client (:id context) (:transaction/client transaction))
_ (assert-can-see-client (:id context) (:payment/client payment))
_ (assert-not-locked (:db/id (:transaction/client transaction)) (:transaction/date transaction))]
(when (not= (:db/id (:transaction/client transaction))
(:db/id (:payment/client payment)))
@@ -448,7 +442,7 @@
(defn match-transaction-autopay-invoices [context {:keys [transaction_id autopay_invoice_ids]} _]
(let [_ (assert-power-user (:id context))
transaction (d-transactions/get-by-id transaction_id)
_ (assert-can-see-client (:id context) (:transaction/client transaction) )
_ (assert-can-see-client (:id context) (:transaction/client transaction))
db (dc/db conn)
invoice-clients (set (map #(pull-ref db :invoice/client %) autopay_invoice_ids))
invoice-amount (reduce + 0.0 (map #(pull-attr db :invoice/total %) autopay_invoice_ids))
@@ -486,7 +480,7 @@
(let [_ (assert-power-user (:id context))
transaction (d-transactions/get-by-id transaction_id)
_ (assert-can-see-client (:id context) (:transaction/client transaction) )
_ (assert-can-see-client (:id context) (:transaction/client transaction))
_ (assert-not-locked (:db/id (:transaction/client transaction)) (:transaction/date transaction))
db (dc/db conn)
invoice-clients (set (map #(pull-ref db :invoice/client %) unpaid_invoice_ids))
@@ -527,8 +521,7 @@
:count Integer/MAX_VALUE} nil)
(filter #(not (:payment %)))
(map :id ))
(map :id))
transaction_ids)
_ (mu/log ::here :txids transaction_ids)
@@ -562,8 +555,7 @@
(:id context))
(doseq [n transactions]
(solr/touch-with-ledger (:db/id n)))
)
(solr/touch-with-ledger (:db/id n))))
(transduce
(comp
(map d-transactions/get-by-id)
@@ -571,7 +563,7 @@
(map ->graphql))
conj
[]
transaction_ids ))
transaction_ids))
(def objects
{:transaction {:fields {:id {:type :id}
@@ -711,7 +703,6 @@
:mutation/match-transaction-unpaid-invoices match-transaction-unpaid-invoices
:mutation/match-transaction-rules match-transaction-rules})
(defn attach [schema]
(->
(merge-with merge schema

View File

@@ -13,7 +13,6 @@
[iol-ion.query :refer [entid]]
[slingshot.slingshot :refer [throw+]]))
(defn snake->kebab [s]
(str/replace s #"_" "-"))
@@ -107,8 +106,6 @@
(#{"manager" "user" "power-user" "read-only"} (:user/role id))
(:user/clients id [])))
(defn result->page [results result-count key args]
{key (map ->graphql results)
:total result-count
@@ -197,7 +194,6 @@
(= :client/code (first x)))
[(entid (dc/db conn) x)]
(sequential? x)
(mapcat coerce-client-ids x)
@@ -221,7 +217,7 @@
(try
(f)
(catch Throwable e
(throw+ (ex-info (.getMessage e) {:type :form-validation
(throw+ (ex-info (.getMessage e) {:type :form-validation
:form-validation-errors [(.getMessage e)]}))
#_(throw (ex-info (.getMessage e)
{:type :notification}

View File

@@ -130,7 +130,6 @@
:vendor/schedule-payment-dom schedule-payment-dom
:vendor/automatically-paid-when-due (:automatically_paid_when_due in)))]
transaction-result (audit-transact [transaction] (:id context))
new-vendor (d-vendors/get-by-id (or (-> transaction-result :tempids (get "vendor"))
id))]
@@ -160,7 +159,6 @@
(audit-transact transaction (:id context))
to))
(defn get-graphql [context args _]
(assert-admin (:id context))
(let [args (assoc args :id (:id context))
@@ -187,7 +185,6 @@
(if-let [query (not-empty (cleanse-query (:query args)))]
(let [search-query (str "name:(" query ")")]
(for [{:keys [id name]} (solr/query solr/impl "vendors" {"query" (cond-> search-query
(not (is-admin? (:id context))) (str " hidden:false"))
"fields" "id, name"})]

View File

@@ -70,7 +70,6 @@
:headers {}
:body ""})
(defn home-handler [{:keys [identity]}]
(if identity
{:status 302
@@ -78,7 +77,6 @@
{:status 302
:headers {"Location" "/login"}}))
(def match->handler-lookup
(-> {:not-found not-found
:home home-handler}
@@ -90,15 +88,13 @@
(merge yodlee2/match->handler)
(merge auth/match->handler)
(merge invoices/match->handler)
(merge exports/match->handler)
))
(merge exports/match->handler)))
(def match->handler
(fn [route]
(or (get match->handler-lookup route)
route)))
(def route-handler
(make-handler all-routes
match->handler))
@@ -125,7 +121,6 @@
uri
:request-method method))
(def auth-backend (jws-backend {:secret (:jwt-secret env) :options {:alg :hs512}}))
(defn wrap-logging [handler]
@@ -159,8 +154,6 @@
:exception e)
(throw e)))))))
(defn wrap-idle-session-timeout
[handler]
(fn [request]

View File

@@ -13,7 +13,7 @@
[iol-ion.utils :refer [remove-nils]]))
(defn get-intuit-bank-accounts
( [db]
([db]
(dc/q '[:find ?external-id ?ba ?c
:in $
:where
@@ -32,7 +32,6 @@
db
client-codes)))
(defn intuit->transaction [transaction]
(let [check-number (when (not (str/blank? (:Num transaction)))
(try
@@ -46,7 +45,6 @@
:transaction/status "POSTED"}
check-number (assoc :transaction/check-number check-number))))
(defn intuits->transactions [transactions bank-account-id client-id]
(->> transactions
(map intuit->transaction)

View File

@@ -11,7 +11,6 @@
(t/is (= #inst "2021-01-01T00:00:00-08:00" (:transaction/date (sut/intuit->transaction (assoc base-transaction :Date "2021-01-01")))))
(t/is (= #inst "2021-06-01T00:00:00-07:00" (:transaction/date (sut/intuit->transaction (assoc base-transaction :Date "2021-06-01")))))))
(t/deftest intuits->transactions
(t/testing "should give unique ids to duplicates"
(t/is (= ["2021-10-11T00:00:00.000-07:00-123-this is a description-45.23-0-345"

View File

@@ -7,8 +7,6 @@
[clojure.data.csv :as csv]
[datomic.api :as dc]))
(def columns [:status :raw-date :description-original :high-level-category nil nil :amount nil nil nil nil nil :bank-account-code :client-code])
(defn tabulate-data [data]
@@ -48,7 +46,7 @@
transactions (->> transactions
(map (fn [t]
(manual->transaction t bank-account-code->bank-account bank-account-code->client)))
(t/apply-synthetic-ids ))]
(t/apply-synthetic-ids))]
(try
(doseq [transaction transactions]
(when-not (seq (:errors transaction))

View File

@@ -40,7 +40,6 @@
db
client-codes))))
(defn plaid->transaction [t plaid-merchant->vendor-id]
(alog/info ::trying-transaction :transaction t)
(cond-> #:transaction {:description-original (:name t)
@@ -66,8 +65,7 @@
:where
[?v :vendor/plaid-merchant ?pm]
[?pm :plaid-merchant/name ?pmn]]
(dc/db conn ))))
(dc/db conn))))
(def single-thread (ex/fixed-thread-executor 1))
@@ -103,13 +101,9 @@
(catch Exception e
(alog/warn ::couldnt-upsert-account :error e))))
(catch Exception e
(alog/warn ::couldnt-upsert-accounts :error e))))
(defn import-plaid-int []
(let [_ (upsert-accounts)
import-batch (t/start-import-batch :import-source/plaid "Automated plaid user")

View File

@@ -29,7 +29,6 @@
nil))
nil))
(defn transaction->existing-payment [_ check-number client-id bank-account-id amount id]
(alog/info ::searching
:client-id client-id
@@ -169,12 +168,10 @@
(= 1234 (extract-check-number {:transaction/description-original "Check abc 1234"}))
(= 1234 (extract-check-number {:transaction/description-original "Check abc 4/10 1234"}))
(= 1234 (extract-check-number {:transaction/description-original "Check abc 4/10 1234 12/3"}))
(= 1234 (extract-check-number {:transaction/description-original "Check abc 4/10 1234"}))
(= 1234 (extract-check-number {:transaction/description-original "Check abc 4/10 1234 12/3"}))
(not= 1234 (extract-check-number {:transaction/description-original "Checkcard 4/10 1234"}))
)
(not= 1234 (extract-check-number {:transaction/description-original "Checkcard 4/10 1234"})))
(defn find-expected-deposit [client-id amount date]
(when date
@@ -187,12 +184,10 @@
[?ed :expected-deposit/date ?d]
[(>= ?d ?d-start)]
[?ed :expected-deposit/total ?a2]
[(auto-ap.utils/dollars= ?a2 ?a)]
]
[(auto-ap.utils/dollars= ?a2 ?a)]]
(dc/db conn) client-id amount (coerce/to-date (t/plus date (t/days -10))))
ffirst)))
(defn categorize-transaction [transaction bank-account existing]
(cond (= :transaction-approval-status/suppressed (existing (:transaction/id transaction)))
:suppressed
@@ -235,7 +230,6 @@
(assoc transaction :transaction/check-number check-number)
transaction))
(defn maybe-clear-payment [{:transaction/keys [check-number client bank-account amount id] :as transaction}]
(when-let [existing-payment (transaction->existing-payment transaction check-number client bank-account amount id)]
(assoc transaction
@@ -266,8 +260,7 @@
:transaction-account/amount amount
:transaction-account/location "A"}]
:transaction/approval-status :transaction-approval-status/approved
:transaction/vendor (:db/id (:expected-deposit/vendor expected-deposit))
))))
:transaction/vendor (:db/id (:expected-deposit/vendor expected-deposit))))))
(defn maybe-code [{:transaction/keys [client amount] :as transaction} apply-rules valid-locations]
(mu/trace
@@ -304,7 +297,6 @@
(maybe-apply-default-vendor)
remove-nils)))
(defn get-existing [bank-account]
(into {}
(dc/q '[:find ?tid ?as2
@@ -317,7 +309,7 @@
(defprotocol ImportBatch
(import-transaction! [this transaction])
(get-stats [this ])
(get-stats [this])
(get-pending-balance [this bank-account])
(finish! [this])
(fail! [this error]))
@@ -326,7 +318,7 @@
:db/id
:bank-account/locations
:bank-account/start-date
{:client/_bank-accounts [:client/code :client/locked-until :client/locations :db/id]} ])
{:client/_bank-accounts [:client/code :client/locked-until :client/locations :db/id]}])
(defn start-import-batch [source user]
(let [stats (atom {:import-batch/imported 0
@@ -335,7 +327,7 @@
:import-batch/not-ready 0
:import-batch/extant 0})
pending-balance (atom {})
extant-cache (atom (cache/ttl-cache-factory {} :ttl 60000 ))
extant-cache (atom (cache/ttl-cache-factory {} :ttl 60000))
import-id (get (:tempids @(dc/transact-async conn [{:db/id "import-batch"
:import-batch/date (coerce/to-date (t/now))
:import-batch/source source
@@ -410,9 +402,7 @@
:import-batch/status :import-status/completed}
@stats)])))))
(defn synthetic-key [{:transaction/keys [date bank-account description-original amount client] } index]
(defn synthetic-key [{:transaction/keys [date bank-account description-original amount client]} index]
(str (str (some-> date coerce/to-date-time atime/localize)) "-" bank-account "-" description-original "-" amount "-" index "-" client))
(defn apply-synthetic-ids [transactions]

View File

@@ -95,5 +95,4 @@
nil)
(Thread/sleep 10000)))))
(def import-yodlee2 (allow-once import-yodlee2-int))

View File

@@ -15,7 +15,6 @@
;; (def base-url "https://sandbox-quickbooks.api.intuit.com/v3")
(def prod-client-id "ABFRwAiOqQiLN66HKplXfyRE3ipD390DHsrUquflRCiOa81mxa")
(def prod-client-secret "xDUj04GeQXpLvrhxep1jjDYwjJWbzzOPrirUQTKF")
@@ -27,11 +26,8 @@
;; "accessToken":,
;;
(def prod-company-id "123146163906404")
(def prod-base-url "https://quickbooks.api.intuit.com/v3")
(defn set-access-token [t]
@@ -53,7 +49,6 @@
:bucket-name "data.prod.app.integreatconsult.com"
:key "intuit/refresh-token")))))
#_{:clj-kondo/ignore [:clojure-lsp/unused-public-var]}
(defn init-tokens [access refresh]
(set-access-token access)
@@ -74,10 +69,9 @@
(defn get-basic-auth []
(Base64/encodeBase64String (.getBytes (str prod-client-id ":" prod-client-secret))))
(defn get-fresh-access-token []
(let [refresh-token (lookup-refresh-token)
response (:body (client/post (str "https://oauth.platform.intuit.com/oauth2/v1/tokens/bearer" )
response (:body (client/post (str "https://oauth.platform.intuit.com/oauth2/v1/tokens/bearer")
{:headers {"Accept" "application/json"
"Content-Type" "application/x-www-form-urlencoded"
@@ -99,16 +93,15 @@
:as :json})
(defn get-bank-accounts-raw [token]
(->> (:body (client/get (str prod-base-url "/company/" prod-company-id "/query" )
(->> (:body (client/get (str prod-base-url "/company/" prod-company-id "/query")
{:headers
(with-auth prod-base-headers token)
:as :json
:query-params {"query" "SELECT * From Account maxresults 1000"}}))
:QueryResponse))
(defn get-bank-accounts [token]
(->> (:body (client/get (str prod-base-url "/company/" prod-company-id "/query" )
(->> (:body (client/get (str prod-base-url "/company/" prod-company-id "/query")
{:headers
(with-auth prod-base-headers token)
:as :json
@@ -124,7 +117,6 @@
:last-updated (c/to-date-time (-> metadata :LastUpdatedTime))
:current-balance (try (double current-balance) (catch Exception _ nil))}))))
(defn get-all-transactions [start end]
(let [token (get-fresh-access-token)]
(:body (client/get (str prod-base-url "/company/" prod-company-id "/reports/TransactionList" "?minorversion=63&start_date=" start "&end_date=" end)

View File

@@ -12,7 +12,6 @@
(defn line->id [{:keys [source id client-code]}]
(str client-code "-" source "-" id))
(defn csv->graphql-rows [lines]
(for [lines (partition-by line->id (drop 1 lines))
:let [{:keys [source client-code date vendor-name note cleared-against] :as line} (first lines)]]

View File

@@ -20,8 +20,7 @@
(mapv (fn [[i]] {:db/id i
:invoice/outstanding-balance 0.0
:invoice/status :invoice-status/paid}))
))
:invoice/status :invoice-status/paid}))))
(alog/info ::closed :count (count invoices-to-close))))

View File

@@ -1,7 +1,7 @@
(ns auto-ap.jobs.core
(:require [auto-ap.utils :refer [heartbeat]]
[mount.core :as mount]
[auto-ap.datomic :refer [conn ]]
[auto-ap.datomic :refer [conn]]
[auto-ap.logging :as alog]
[nrepl.server :refer [start-server]]
[auto-ap.background.metrics :refer [metrics-setup container-tags container-data logging-context]]
@@ -14,7 +14,7 @@
(mu/trace ::execute-background-job
[]
(try
(mount/start (mount/only #{#'conn #'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))
((heartbeat f name))
(alog/info ::stopping :job name)

View File

@@ -29,7 +29,6 @@
:body {:html (str "<div>You can download the original email <a href=\"" target-url "\">here</a>.<p><pre>" message "</pre></p></div>")
:text (str "<div>You can download the original email here: " target-url)}}})))
(defn process-sqs []
(alog/info ::fetching-sqs)
(doseq [message (:messages (sqs/receive-message {:queue-url (:invoice-import-queue-url env)
@@ -79,27 +78,20 @@
(defn -main [& _]
(execute "import-uploaded-invoices" process-sqs))
(comment
(with-open [i (io/output-stream "/tmp/bryce.pdf")]
(clojure.java.io/copy
(-> (s3/get-object :bucket-name (:data-bucket env)
:key "invoice-files/f0e73dcb-e5e5-4c81-b82b-319b7caedacf.pdf"
:key "invoice-files/f0e73dcb-e5e5-4c81-b82b-319b7caedacf.pdf")
)
:input-stream)
i))
(parse/parse-file "/tmp/bryce.pdf" "/tmp/bryce.pdf")
(-> (clojure.java.shell/sh "pdftotext" "-layout" "/tmp/bryce.pdf" "-")
:out
)
:out)
1
(user/init-repl)
)
(user/init-repl))

View File

@@ -10,13 +10,12 @@
[config.core :refer [env]]
[datomic.api :as dc]))
(defn historical-load-sales [client days]
(alog/info ::new-sales-loading :client (:client/code client) :days days)
(let [client (dc/pull (dc/db auto-ap.datomic/conn)
square3/square-read
client)
days (cond-> days (string? days) ( #(Long/parseLong %)))]
days (cond-> days (string? days) (#(Long/parseLong %)))]
(doseq [square-location (:client/square-locations client)
:when (:square-location/client-location square-location)]
@@ -31,11 +30,10 @@
@(square3/upsert-refunds client square-location)
@(square3/upsert-payouts client square-location (time/plus (time/now) (time/days (- days))) (time/now)))))
(defn load-historical-sales [args]
(let [{:keys [days client]} args
client (cond-> client
( string? client) ( #( Long/parseLong %)))]
(string? client) (#(Long/parseLong %)))]
(historical-load-sales client days)))
(defn -main [& _]

View File

@@ -28,12 +28,10 @@
(defn read-xml [stream]
(-> (slurp stream)
(.getBytes)
(java.io.ByteArrayInputStream. )
(java.io.ByteArrayInputStream.)
xml/parse
zip/xml-zip))
(defn mark-key [k]
(s3/copy-object {:source-bucket-name bucket-name
:destination-bucket-name bucket-name
@@ -71,10 +69,10 @@
(drop 1)
#_(filter (fn [[_ _ _ _ _ _ _ _ _ _ _ break-flag]]
(= "Y" break-flag)))
(map (fn [[_ location-hint invoice-number ship-date invoice-total ]]
(map (fn [[_ location-hint invoice-number ship-date invoice-total]]
(let [matching-client (and location-hint
(parse/exact-match clients location-hint))
location (parse/best-location-match matching-client location-hint location-hint )
location (parse/best-location-match matching-client location-hint location-hint)
vendor (d/pull (d/db conn) '[:vendor/default-account] :vendor/general-produce)]
(when-not (and matching-client
(not (@missing-client-hints location-hint))
@@ -99,8 +97,7 @@
(-> vendor :vendor/default-account :db/id)
:invoice-expense-account/location location
:invoice-expense-account/amount (Math/abs (Double/parseDouble invoice-total))
:db/id (random-tempid)
}]})))
:db/id (random-tempid)}]})))
(filter :invoice/client)
(reduce (fn [[seen-so-far list] i]
(let [k [(:invoice/invoice-number i) (:invoice/client i)]]
@@ -108,8 +105,7 @@
[seen-so-far list]
[(conj seen-so-far k) (conj list i)])))
[#{} []])
(second)
)
(second))
(catch Exception e
(log/error ::cant-import-general-produce
:error e)
@@ -123,7 +119,7 @@
(defn zip-seq [zipper]
(->> (zip/xml-zip (zip/node zipper))
(iterate zip/next )
(iterate zip/next)
(take-while (complement zip/end?))))
(defmethod extract-invoice-details :cintas
@@ -160,7 +156,7 @@
atime/localize
(atime/unparse atime/iso-date)
(atime/parse atime/iso-date))))
location (parse/best-location-match matching-client location-hint location-hint )
location (parse/best-location-match matching-client location-hint location-hint)
due (-> invoice-date
(time/plus (time/days 30))
(coerce/to-date))
@@ -178,7 +174,7 @@
:content
first
Double/parseDouble)
invoice {:db/id (random-tempid )
invoice {:db/id (random-tempid)
:invoice/vendor :vendor/cintas
:invoice/import-status :import-status/imported
:invoice/status :invoice-status/unpaid
@@ -206,8 +202,7 @@
(-> vendor :vendor/default-account :db/id)
:invoice-expense-account/location location
:invoice-expense-account/amount (Math/abs total)
:db/id (random-tempid)
}]}]
:db/id (random-tempid)}]}]
(log/info ::cintas-invoice-importing
:invoice invoice)
[invoice])
@@ -232,7 +227,7 @@
(s3/copy-object {:source-bucket-name bucket-name
:destination-bucket-name bucket-name
:source-key k
:destination-key invoice-key })
:destination-key invoice-key})
invoice-key))
(defn get-all-keys
@@ -240,7 +235,7 @@
(let [first-page-result (s3/list-objects-v2 {:bucket-name bucket-name
:prefix "ntg-invoices/pending"})]
(lazy-seq (concat (:object-summaries first-page-result) (get-all-keys (:next-continuation-token first-page-result))))))
([next-token ]
([next-token]
(when next-token
(let [page-result (s3/list-objects-v2 {:bucket-name bucket-name
:prefix "ntg-invoices/pending"
@@ -250,8 +245,7 @@
(lazy-seq (concat (:object-summaries page-result) (get-all-keys (:next-continuation-token page-result)))))))))
(defn recent? [k]
(time/after? (:last-modified k) (time/plus (time/now) (time/days -15)))
)
(time/after? (:last-modified k) (time/plus (time/now) (time/days -15))))
(defn import-ntg-invoices
([] (import-ntg-invoices (->> (get-all-keys)
@@ -268,7 +262,7 @@
:where [?c :client/code]]
(d/db conn)))]
(log/info ::found-invoice-keys
:keys keys )
:keys keys)
(let [transaction (->> keys
(mapcat (fn [k]
(try
@@ -304,6 +298,5 @@
(doseq [k keys]
(mark-key k)))))
(defn -main [& _]
(execute "ntg" import-ntg-invoices))

View File

@@ -45,8 +45,7 @@
(reduce + 0.0
(->> values
(map (fn [[_ _ _ _ amount]]
(- (Double/parseDouble amount))))))
]))
(- (Double/parseDouble amount))))))]))
(into {}))]
(->>
(for [[i
@@ -76,27 +75,22 @@
target-date (coerce/to-date (atime/parse target-date atime/normal-date))
current-date (:invoice/date invoice)
current-expense-account-amount (:invoice-expense-account/amount invoice-expense-account 0.0)
target-expense-account-amount (- (Double/parseDouble amount))
current-expense-account-location (:invoice-expense-account/location invoice-expense-account)
target-expense-account-location location
[[_ _ invoice-payment]] (vec (dc/q
'[:find ?p ?a ?ip
:in $ ?i
:where [?ip :invoice-payment/invoice ?i]
[?ip :invoice-payment/amount ?a]
[?ip :invoice-payment/payment ?p]
]
[?ip :invoice-payment/payment ?p]]
db invoice-id))]
:when current-total]
[
(when (not (dollars= current-total target-total))
[(when (not (dollars= current-total target-total))
{:db/id invoice-id
:invoice/total target-total})
@@ -129,7 +123,7 @@
{:db/id invoice-expense-account-id
:invoice-expense-account/location target-expense-account-location})
(when (not= current-account-id target-account-id )
(when (not= current-account-id target-account-id)
{:db/id invoice-expense-account-id
:invoice-expense-account/account target-account-id})])
(mapcat identity)

View File

@@ -38,9 +38,6 @@
(recur next-deps (into order next-order))
(into order next-order)))))
(def loaded (atom #{}))
(defn upsert-batch
@@ -112,7 +109,6 @@
{:entity/migration-key 17592263907739}
{:entity/migration-key 17592271516922}])
(doseq [entity (cond->> (order-of-insert entity-dependencies)
true (filter #(not= "audit" %))
starting-at (drop-while #(not= starting-at %)))
@@ -136,7 +132,6 @@
(mu/log ::refresh-running-balance-cache-complete)
(mu/log ::done))
(defn -main [& _]
(try
(println "restore")
@@ -156,8 +151,6 @@
;; /datomic-backup/079df203-eae0-4acf-94d5-8608ba8b8a9a
(load-from-backup "079df203-eae0-4acf-94d5-8608ba8b8a9a" auto-ap.datomic/conn ["charge"])
(load-entity "charge" (ednl/slurp "/tmp/tmp-edn"))
(load-entity "charge" (ednl/slurp "/tmp/tmp-edn")))
)
;; => nil

View File

@@ -39,18 +39,15 @@
(dc/db conn)
number)))
(defn delete-all []
@(dc/transact-async conn
(->>
(dc/q '[:find ?ss
:where [?ss :sales-summary/date]]
(dc/db conn))
(map (fn [[ ss]]
(map (fn [[ss]]
[:db/retractEntity ss])))))
(defn dirty-sales-summaries [c]
(let [client-id (dc/entid (dc/db conn) c)]
(->> (dc/index-pull (dc/db conn)
@@ -192,8 +189,6 @@
:ledger-mapped/amount v
:ledger-mapped/ledger-side :ledger-side/credit}))))
(defn get-fees [c date]
(when-let [fee (get-fee c date)]
{:db/id (str (java.util.UUID/randomUUID))
@@ -315,7 +310,6 @@
@(dc/transact conn [[:upsert-sales-summary result]]))
@(dc/transact conn [{:db/id id :sales-summary/dirty false}]))))))
(defn reset-summaries []
@(dc/transact conn (->> (dc/q '[:find ?sos
:in $
@@ -324,9 +318,6 @@
(map (fn [[sos]]
[:db/retractEntity sos])))))
(comment
(auto-ap.datomic/transact-schema conn)
@@ -336,26 +327,19 @@
(dirty-sales-summaries [:client/code "NGWH"])
(apply mark-dirty [:client/code "NGWH"] (last-n-days 5))
(iol-ion.tx.upsert-sales-summary-ledger/summary->journal-entry (dc/db conn) 17592314245819)
(iol-ion.tx.upsert-sales-summary-ledger/upsert-sales-summary (dc/db conn) {:db/id 17592314241429})
(mark-all-dirty 5)
(delete-all)
(sales-summaries-v2)
1
(dc/q '[:find (pull ?sos [* {:sales-summary/sales-items [*]}])
:in $
:where [?sos :sales-summary/client [:client/code "NGHW"]]
@@ -386,15 +370,7 @@
@(dc/transact conn [{:db/id :sales-summary/total-tax :db/ident :sales-summary/total-tax-legacy}
{:db/id :sales-summary/total-tip :db/ident :sales-summary/total-tip-legacy}])
(auto-ap.datomic/transact-schema conn)
)
(auto-ap.datomic/transact-schema conn))
(defn -main [& _]
(execute "sales-summaries" sales-summaries-v2))

View File

@@ -44,7 +44,6 @@
(dc/db conn)
50000))))
(def ^:dynamic bucket-name (:data-bucket env))
(def header-keys ["TransCode" "GroupID" "Company" "CustomerNumber" "InvoiceNumber" "RecordType" "Item" "InvoiceDocument" "AccountName" "AccountDunsNo" "InvoiceDate" "AccountDate" "CustomerPONo" "PaymentTerms" "TermsDescription" "StoreNumber" "CustomerName" "AddressLine1" "AddressLine2" "City1" "State1" "Zip1" "Phone1" "Duns1" "Hin1" "Dea1" "TIDCustomer" "ChainNumber" "BidNumber" "ContractNumber" "CompanyNumber" "BriefName" "Address" "Address2" "City2" "State2" "Zip2" "Phone2" "Duns2" "Hin2" "Dea2" "Tid_OPCO" "ObligationIndicator" "Manifest" "Route" "Stop" "TermsDiscountPercent" "TermsDiscountDueDate" "TermsNetDueDate" "TermsDiscountAmount" "TermsDiscountCode" "OrderDate" "DepartmentCode"])
@@ -64,7 +63,6 @@
first
first)))
(defn read-sysco-csv [k]
(-> (s3/get-object {:bucket-name bucket-name
:key k})
@@ -84,11 +82,9 @@
(fn [acc row]
(update acc (get-line-account (nth row item-name-index))
(fnil + 0.0)
(Double/parseDouble (nth row item-price-index))
)
)
{})
)
(Double/parseDouble (nth row item-price-index))))
{}))
items-with-tax (update items (get-line-account "TAX")
(fnil + 0.0)
tax)
@@ -153,9 +149,9 @@
:client/locations]
(:db/id matching-client))
location-hint
location-hint )
location-hint)
:date (coerce/to-date date)
:vendor (:db/id sysco-vendor )
:vendor (:db/id sysco-vendor)
:client (:db/id matching-client)
:import-status :import-status/imported
:status :invoice-status/unpaid
@@ -182,39 +178,30 @@
(defn get-test-invoice-file
([] (get-test-invoice-file 999))
( [i]
([i]
(nth (->> (s3/list-objects-v2 {:bucket-name "data.prod.app.integreatconsult.com"
:prefix "sysco/imported"})
:object-summaries
(map :key)
)
(map :key))
i)))
(comment
(with-bindings { #'bucket-name "data.prod.app.integreatconsult.com"}
(with-bindings {#'bucket-name "data.prod.app.integreatconsult.com"}
(doall
(for [n (range 930 940 )
(for [n (range 930 940)
:let [result (-> (get-test-invoice-file n)
read-sysco-csv
(extract-invoice-details (get-sysco-vendor))
)]
(extract-invoice-details (get-sysco-vendor)))]
#_#_:when (not (check-okay-amount? result))]
result)))
(with-bindings { #'bucket-name "data.prod.app.integreatconsult.com"}
(with-bindings {#'bucket-name "data.prod.app.integreatconsult.com"}
(let [result (-> "sysco/error/SYSCO050_00175962_20241010122639019.csv"
read-sysco-csv
(extract-invoice-details (get-sysco-vendor))
)]
(extract-invoice-details (get-sysco-vendor)))]
result))
)
result)))
(defn import-sysco []
(let [sysco-vendor (get-sysco-vendor)
@@ -223,7 +210,6 @@
:object-summaries
(map :key))]
(alog/info ::importing-sysco
:count (count keys)
:keys (pr-str keys))
@@ -256,6 +242,5 @@
(doseq [k keys]
(mark-key k))))
(defn -main [& _]
(execute "sysco" import-sysco))

View File

@@ -18,23 +18,20 @@
(t/plus (t/months -6))
(c/to-date))))
([start-date]
(let [txes-missing-ledger-entries (->> (dc/q {:find ['?t ]
(let [txes-missing-ledger-entries (->> (dc/q {:find ['?t]
:in ['$ '?sd]
:where [
'[?t :transaction/date ?d]
:where ['[?t :transaction/date ?d]
'[(>= ?d ?sd)]
'(not [_ :journal-entry/original-entity ?t])
'(not [?t :transaction/amount 0.0])
'(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])]}
(dc/db conn) start-date)
(map first)
(mapv (fn [t]
[:upsert-transaction {:db/id t}])))
invoices-missing-ledger-entries (->> (dc/q {:find ['?t ]
invoices-missing-ledger-entries (->> (dc/q {:find ['?t]
:in ['$ '?sd]
:where ['[?t :invoice/date ?d]
'[(>= ?d ?sd)]
@@ -43,21 +40,19 @@
'[(not= 0.0 ?amt)]
'(not [?t :invoice/status :invoice-status/voided])
'(not [?t :invoice/import-status :import-status/pending])
'(not [?t :invoice/exclude-from-ledger true])
]}
'(not [?t :invoice/exclude-from-ledger true])]}
(dc/db conn) start-date)
(map first)
(mapv (fn [i]
[:upsert-invoice {:db/id i}])))
sales-summaries-missing-ledger-entries (->> (dc/q {:find ['?ss ]
sales-summaries-missing-ledger-entries (->> (dc/q {:find ['?ss]
:in ['$ '?sd]
:where ['[?ss :sales-summary/date ?d]
'[(>= ?d ?sd)]
'(not [_ :journal-entry/original-entity ?ss])
'[?ss :sales-summary/items ?item]
'[?item :ledger-mapped/account]
]}
'[?item :ledger-mapped/account]]}
(dc/db conn) start-date)
(map first)
(mapv (fn [ss]
@@ -72,7 +67,6 @@
:sales-summary-count (count sales-summaries-missing-ledger-entries))
@(dc/transact conn repairs)))))
(defn touch-transaction [e]
@(dc/transact conn [{:db/id "datomic.tx"
:db/doc "touching transaction to update ledger"}
@@ -83,8 +77,6 @@
:db/doc "touching invoice to update ledger"}
[:upsert-invoice {:db/id e}]]))
(defn recently-changed-entities [start end]
(into #{}
(map first)
@@ -97,7 +89,7 @@
(defn mismatched-transactions
([]
(mismatched-transactions (c/to-date (t/minus (t/now) (t/days 7)))
(c/to-date (t/minus (t/now) (t/hours 1)))) )
(c/to-date (t/minus (t/now) (t/hours 1)))))
([changed-between-start changed-between-end]
(mu/trace ::calculating-mismatched-transactions
[:range {:start changed-between-start
@@ -109,7 +101,7 @@
:count (count entities-to-consider))
jel-accounts (reduce
(fn [acc [e lia]]
(update acc e (fnil conj #{} ) lia))
(update acc e (fnil conj #{}) lia))
{}
(dc/q '[:find ?e ?lia
:in $ [?e ...]
@@ -123,7 +115,7 @@
entities-to-consider))
transaction-accounts (reduce
(fn [acc [e lia]]
(update acc e (fnil conj #{} ) lia))
(update acc e (fnil conj #{}) lia))
{}
(dc/q '[:find ?e ?lia
:in $ [?e ...]
@@ -154,8 +146,7 @@
:where [?je :journal-entry/amount ?a]
[?je :journal-entry/line-items ?jel]
[(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]]
(dc/db conn)
entities-to-consider)
(filter (fn [[_ a d c]]
@@ -165,8 +156,6 @@
(map (fn [je]
(pull-ref (dc/db conn) :journal-entry/original-entity je)))))))
(defn unbalanced-invoices
([] (unbalanced-invoices (c/to-date (t/minus (t/now) (t/days 7)))
(c/to-date (t/minus (t/now) (t/hours 1)))))
@@ -195,13 +184,13 @@
(defn mismatched-invoices
([]
(mismatched-invoices (c/to-date (t/minus (t/now) (t/days 7)))
(c/to-date (t/minus (t/now) (t/hours 1)))) )
(c/to-date (t/minus (t/now) (t/hours 1)))))
([changed-between-start changed-between-end]
(let [entities-to-consider (recently-changed-entities changed-between-start changed-between-end)
jel-accounts (reduce
(fn [acc [e lia]]
(update acc e (fnil conj #{} ) lia))
(update acc e (fnil conj #{}) lia))
{}
(dc/q '[:find ?e ?lia
:in $ [?e ...]
@@ -216,7 +205,7 @@
entities-to-consider))
invoice-accounts (reduce
(fn [acc [e lia]]
(update acc e (fnil conj #{} ) lia))
(update acc e (fnil conj #{}) lia))
{}
(dc/q '[:find ?e ?lia
:in $ [?e ...]
@@ -230,8 +219,7 @@
(not [?e :invoice/exclude-from-ledger true])
[?e :invoice/import-status :import-status/imported]]
(dc/db conn)
entities-to-consider))
]
entities-to-consider))]
(filter
(fn [[e accounts]]
(not= accounts (get jel-accounts e)))
@@ -272,7 +260,6 @@
(statsd/gauge "data.unbalanced_transactions" (count (unbalanced-transactions))))
(statsd/gauge "data.unbalanced_transactions" 0.0))))
(mu/trace ::fixing-mismatched-invoices
[]
(mu/log ::started-fixing-mismatched-invoices)
@@ -308,16 +295,14 @@
:priority :low}
nil))
(defn build-account-lookup [client-id]
(let [accounts (by :db/id (map first (dc/q {:find ['(pull ?e [:db/id :account/name
:account/numeric-code
{: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 ['$]
:where ['[?e :account/name]]}
(dc/db conn ))))
(dc/db conn))))
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 ['$]
@@ -329,9 +314,8 @@
(map (fn [o]
[[(:db/id a) (:db/id (:account-client-override/client o))]
(:account-client-override/name o)])
(:account/client-overrides a))
) )
(into {} ))]
(:account/client-overrides a))))
(into {}))]
(fn [a]
{:name (or (:bank-account/name (bank-accounts a))
(overrides-by-client [a client-id])
@@ -356,8 +340,7 @@
:selector [:db/id :journal-entry-line/location :journal-entry-line/account :journal-entry-line/client+account+location+date {:journal-entry/_line-items [:journal-entry/date :journal-entry/client]}]
:start [:journal-entry-line/client+account+location+date [c]]})
(take-while (fn [result]
(= c (first (:journal-entry-line/client+account+location+date result)))
))
(= c (first (:journal-entry-line/client+account+location+date result)))))
(filter (fn [{index :journal-entry-line/client+account+location+date :as result}]
(not= index
[(-> result :journal-entry/_line-items :journal-entry/client :db/id)
@@ -383,7 +366,7 @@
(filter (comp available :db/id) clients)
clients)))
#_(clients-needing-refresh (dc/db conn) #{ 17592273679867})
#_(clients-needing-refresh (dc/db conn) #{17592273679867})
#_(comment [17592334354011 #inst "0024-08-03T07:52:58.000-00:00"]
[17592302554688 #inst "0023-07-20T07:52:58.000-00:00"]
@@ -502,10 +485,10 @@
#_(do
(mu/with-context {:service "upsert-running-balance"
:source "upsert-running-balance" }
:source "upsert-running-balance"}
(mu/trace ::updating-balance
[:service "upsert-running-balance"
:source "upsert-running-balance" ]
:source "upsert-running-balance"]
(let [db (dc/db conn)
starting-at (c/to-date (t/now))
_ (mark-client-dirty "NGA1")
@@ -556,9 +539,9 @@
(mark-client-dirty "NGA1")
(mark-all-clients-dirty)
(mark-all-clients-dirty)
(count (clients-needing-refresh (dc/db conn)))
(count (clients-needing-refresh (dc/db conn)))
(upsert-running-balance)
@@ -580,18 +563,14 @@
:journal-entry-line/date date
:journal-entry-line/client client})
{:user/name "backfill-client and dates"})
(println "done."))
#_(dc/q '[:find (pull ?je [*]) (pull ?jel [*])
:where [?je :journal-entry/line-items ?jel]
(not [?jel :journal-entry-line/running-balance-tuple])]
(dc/db conn)))
;; TODO only enable once IOL is set up in clod
#_{:clj-kondo/ignore [:clojure-lsp/unused-public-var]}
(mount/defstate running-balance-cache-worker

View File

@@ -1,7 +1,6 @@
(ns auto-ap.logging
(:require [com.brunobonacci.mulog :as mu]))
(defmacro with-context-as [ctx s & body]
`(mu/with-context ~ctx
(let [~s (mu/local-context)]
@@ -12,13 +11,13 @@
~@body))
(defmacro info [x & kvs]
`(mu/log ~x :status "INFO" ~@kvs ))
`(mu/log ~x :status "INFO" ~@kvs))
(defmacro warn [x & kvs]
`(mu/log ~x :status "WARN" ~@kvs ))
`(mu/log ~x :status "WARN" ~@kvs))
(defmacro error [x & kvs]
`(mu/log ~x :status "ERROR" ~@kvs ))
`(mu/log ~x :status "ERROR" ~@kvs))
(defn peek
([x]

View File

@@ -16,7 +16,6 @@
(defonce last-text (atom nil))
(defn template-applies? [text {:keys [keywords]}]
(every? #(re-find % text) keywords))
@@ -60,8 +59,6 @@
first
(extract-template text)))
(defmulti parse-file
"Parses a file based on its extension. Accepts options as additional arguments.
Options:
@@ -75,7 +72,6 @@
(json/write-str
(alog/peek ::x {"url" (str "https://" "data.prod.app.integreatconsult.com" "/" f)}))})))]
(alog/info ::glimpse2-payload :payload result)
(-> result
json/read-str)))
@@ -123,7 +119,6 @@
[file filename & _]
(excel/parse-file file filename))
(defmethod parse-file
"xlsx"
[file filename & _]

View File

@@ -23,7 +23,6 @@
(str/includes? (str header) "Document Number")
:philz
(str/includes? (str header) "DISCOUNT_MESSAGE")
:wismettac
@@ -53,8 +52,7 @@
(try
(u/parse-value :clj-time f d)
(catch Exception _
nil))
))
nil))))
(first))]
(u/parse-value :clj-time valid-fmt d)))
@@ -109,7 +107,7 @@
(map (fn [[_ po-number _ invoice-number invoice-date customer value :as row]]
{:vendor-code "Mama Lu's Foods"
:customer-identifier customer
:invoice-number (str po-number "-" invoice-number )
:invoice-number (str po-number "-" invoice-number)
:date (parse-date-fallover invoice-date ["M/d/yyyy HH:ss" "M/d/yyyy HH:mm:ss aa" "M/d/yyyy"])
:total (str/replace value #"," "")
:text (str/join " " row)
@@ -122,10 +120,10 @@
[rows]
(transduce
(comp (drop 1)
(map (fn [[ po-number _ invoice-number invoice-date customer value :as row]]
(map (fn [[po-number _ invoice-number invoice-date customer value :as row]]
{:vendor-code "Mama Lu's Foods"
:customer-identifier customer
:invoice-number (str po-number "-" invoice-number )
:invoice-number (str po-number "-" invoice-number)
:date (parse-date-fallover invoice-date ["M/d/yyyy HH:ss" "M/d/yyyy HH:mm:ss aa" "M/d/yyyy"])
:total (str/replace value #"," "")
:text (str/join " " row)
@@ -138,7 +136,7 @@
[rows]
(transduce
(comp
(filter (fn [[_ _ _ _ _ status _ _ _ ]]
(filter (fn [[_ _ _ _ _ status _ _ _]]
(= status "Billed")))
(map (fn [[dt _ doc-number name _ _ _ _ amount :as row]]
{:vendor-code "PHILZ COFFEE, INC"
@@ -147,10 +145,8 @@
:date (some-> dt not-empty (parse-date-fallover ["MM/dd/yyyy"]))
:total (str/replace amount #"," "")
:text (str/join " " row)
:full-text (str/join " " row)}))
:full-text (str/join " " row)})))
)
conj
[]
(drop 1 rows)))
@@ -165,8 +161,7 @@
:date (some-> inv_dt not-empty (parse-date-fallover ["MM/dd/yyyy"]))
:total (str/replace total #"," "")
:text (str/join " " row)
:full-text (str/join " " row)}))
)
:full-text (str/join " " row)})))
conj
[]
(drop 1 rows)))
@@ -182,8 +177,7 @@
:due (some-> due not-empty (parse-date-fallover ["MM/dd/yy"]))
:total (str/replace amount #"[\$,]" "")
:text (str/join " " row)
:full-text (str/join " " row)}))
)
:full-text (str/join " " row)})))
conj
[]
(drop 1 rows)))
@@ -199,8 +193,7 @@
:date (some-> date not-empty (parse-date-fallover ["MM/dd/yy"]))
:total (str/replace amount #"[\$,]" "")
:text (str/join " " row)
:full-text (str/join " " row)}))
)
:full-text (str/join " " row)})))
conj
[]
(drop 1 rows)))

View File

@@ -6,10 +6,7 @@
[clojure.data.json :as json]
[config.core :refer [env]]
[clojure.java.io :as io]
[amazonica.aws.s3 :as s3])
)
[amazonica.aws.s3 :as s3]))
(defn template-applies? [text {:keys [keywords]}]
@@ -29,16 +26,15 @@
(re-find regex (str (d/read-cell cell)))))
(map (fn [cell]
(let [address (.getAddress cell)
cell-value (str (d/read-cell (d/select-cell (.toString (CellAddress. (+ offset-row (.getRow address)) (+ offset-column (.getColumn address)) ))
cell-value (str (d/read-cell (d/select-cell (.toString (CellAddress. (+ offset-row (.getRow address)) (+ offset-column (.getColumn address))))
(first (d/sheet-seq wb)))))
raw-result (if extract-regex
(second (re-find extract-regex cell-value))
cell-value)]
(if (get parser k)
(u/parse-value (first (get parser k) ) (second (get parser k) ) raw-result)
raw-result
))))
(u/parse-value (first (get parser k)) (second (get parser k)) raw-result)
raw-result))))
first)))
{:vendor-code vendor}
extract)]))
@@ -67,9 +63,6 @@
first
(extract sheet))))
(defn xls-date->date [f]
(when (not-empty f)
(let [f (Double/parseDouble f)

View File

@@ -8,11 +8,9 @@
(defmulti parse-value (fn [method _ _]
method))
(defmethod parse-value :trim-commas
[_ _ value]
(str/replace value #"," "")
)
(str/replace value #"," ""))
(defmethod parse-value :trim-commas-and-remove-dollars
[_ _ value]
(str/replace (str/replace value #"," "") #"\$" ""))
@@ -20,7 +18,7 @@
(defmethod parse-value :trim-commas-and-remove-dollars-and-invert-parentheses
[_ _ value]
(let [v (str/replace (str/replace value #"," "") #"\$" "")]
(if-let [[_ a ] (re-find #"\((.*)\)" v)]
(if-let [[_ a] (re-find #"\((.*)\)" v)]
(str "-" a)
v)))
@@ -40,11 +38,10 @@
(let [format "yyyy-MM-dd"
[month day year] (str/split (-> value
(str/replace #"\s+" " ")
)
(str/replace #"\s+" " "))
#"\s")
value (str "20" year "-" month "-" day) ]
value (str "20" year "-" month "-" day)]
(try
(time/from-time-zone (f/parse (f/formatter format) value)
(time/time-zone-for-id "America/Los_Angeles"))
@@ -66,8 +63,7 @@
(alog/warn ::cant-parse-date :error e :raw-value (str value))
nil)))
nil
format)
))
format)))
(defmethod parse-value nil
[_ _ value]

View File

@@ -47,8 +47,7 @@
(:color cell) (assoc :color (:color cell))
(:bg-color cell) (assoc :background-color (:bg-color cell)))
cell-contents
]))
cell-contents]))
(defn cell-count [table]
(let [counts (map count (:rows table))]
@@ -77,15 +76,13 @@
:else
100)}
widths
]
widths]
(into
(for [row (:rows table)]
(into []
(for [cell (take cell-count (concat row (repeat nil)))]
(cell->pdf cell)
))))
(cell->pdf cell)))))
(conj (take cell-count (repeat (cell->pdf {:value " "})))))))
(defn split-table [table n]
@@ -177,7 +174,7 @@
(conj [:paragraph {:color [128 0 0] :size 9} (:warning report)])
(conj
(table->pdf report
(cond-> (into [30 ] (repeat client-count 13))
(cond-> (into [30] (repeat client-count 13))
(:include-comparison args) (into (repeat (* 2 client-count) 13))
(and (> client-count 1) (not (:include-comparison args))) (conj 13)))))
output-stream)
@@ -192,10 +189,8 @@
(mapcat (fn [p1 p2]
(map
(fn [a]
(assoc a :period p1)
)
(:accounts p2))
)
(assoc a :period p1))
(:accounts p2)))
(:periods args)))
pnl-data (l-reports/->PNLData args data (by :db/id :client/code clients))
report (l-reports/summarize-pnl pnl-data)
@@ -203,11 +198,11 @@
(pdf/pdf
(-> [{:left-margin 10 :right-margin 10 :top-margin 5 :bottom-margin 15
:size (cond
(and (>= (count (-> pnl-data :args :periods)) 8 )
(and (>= (count (-> pnl-data :args :periods)) 8)
(-> pnl-data :args :include-deltas))
:a2
(>= (count (-> pnl-data :args :periods)) 4 )
(>= (count (-> pnl-data :args :periods)) 4)
:tabloid
:else
:letter)
@@ -238,10 +233,8 @@
(mapcat (fn [p1 p2]
(map
(fn [a]
(assoc a :period p1)
)
(:accounts p2))
)
(assoc a :period p1))
(:accounts p2)))
(:periods args)))
pnl-data (l-reports/->PNLData args data (by :db/id :client/code clients))
report (l-reports/summarize-cash-flows pnl-data)
@@ -249,11 +242,11 @@
(pdf/pdf
(-> [{:left-margin 10 :right-margin 10 :top-margin 5 :bottom-margin 15
:size (cond
(and (>= (count (-> pnl-data :args :periods)) 8 )
(and (>= (count (-> pnl-data :args :periods)) 8)
(-> pnl-data :args :include-deltas))
:a2
(>= (count (-> pnl-data :args :periods)) 4 )
(>= (count (-> pnl-data :args :periods)) 4)
:tabloid
:else
:letter)
@@ -296,7 +289,7 @@
(.toByteArray output-stream)))
(defn join-names [client-ids]
(str/replace (->> client-ids (pull-many (dc/db conn) [:client/name]) (map :client/name) (str/join "-")) #"[^\w]" "_" ))
(str/replace (->> client-ids (pull-many (dc/db conn) [:client/name]) (map :client/name) (str/join "-")) #"[^\w]" "_"))
(defn pnl-args->name [args]
(let [min-date (atime/unparse-local
@@ -354,7 +347,7 @@
:report/creator (:user user)
:report/created (java.util.Date.)}])
{:report/name name
:report/url url }))
:report/url url}))
(defn print-cash-flows [user args data]
(let [uuid (str (UUID/randomUUID))
@@ -375,7 +368,7 @@
:report/creator (:user user)
:report/created (java.util.Date.)}])
{:report/name name
:report/url url }))
:report/url url}))
(defn print-balance-sheet [user args data]
(let [uuid (str (UUID/randomUUID))
@@ -396,7 +389,7 @@
:report/creator (:user user)
:report/created (java.util.Date.)}])
{:report/name name
:report/url url }))
:report/url url}))
(defn print-journal-detail-report [user args data]
(let [uuid (str (UUID/randomUUID))
@@ -417,4 +410,4 @@
:report/creator (:user user)
:report/created (java.util.Date.)}])
{:report/name name
:report/url url }))
:report/url url}))

View File

@@ -40,8 +40,6 @@
:body
:link_token))
(defn exchange-public-token [public-token _]
(-> (client/post (str base-url "/item/public_token/exchange")
{:as :json
@@ -87,9 +85,7 @@
(.getMessage (:throwable &throw-context)))
json))))))
(defn get-balance [access-token ]
(defn get-balance [access-token]
(-> (client/post (str base-url "/accounts/balance/get")
{:as :json
:headers {"Content-Type" "application/json"}
@@ -104,7 +100,6 @@
:end (str end)
:acct (str account-id))
(try+
(-> (client/post (str base-url "/transactions/get")
{:as :json
@@ -140,6 +135,4 @@
(clojure.pprint/pprint
(get-transactions "access-production-c0e322fa-f33d-4806-bc42-5fc883fb1ba4" "VZ8Y1azZMdhoYo9MQABrfpgz4jm4kPtakyxN5" #clj-time/date-time "2024-03-15" #clj-time/date-time "2024-03-30"))
(clojure.pprint/pprint (get-accounts "access-production-c0e322fa-f33d-4806-bc42-5fc883fb1ba4"))
)
(clojure.pprint/pprint (get-accounts "access-production-c0e322fa-f33d-4806-bc42-5fc883fb1ba4")))

View File

@@ -76,10 +76,8 @@
(double? v)
(str v)
:else
v)
]))
v)]))
m))
(defn export-invoices [{:keys [query-params identity]}]
@@ -90,7 +88,7 @@
(list (into (list)
(map datomic-map->graphql-map)
(map first (dc/q '[:find (pull ?i [:db/id :invoice/total :invoice/outstanding-balance :invoice/invoice-number :invoice/date :invoice/original-id
{ :invoice/status [:db/ident]
{:invoice/status [:db/ident]
:invoice/payments
[:invoice-payment/amount
{:invoice-payment/payment [:payment/check-number
@@ -124,13 +122,11 @@
[:invoices [[:invoice [:id :original-id]] :amount]]
[:bank-account [:number :code :bank-name :bank-code :id]]
[:vendor [:name :id [:primary-contact [:name :email :phone]] [:default-account [:name :numeric-code :id]] [:address [:street1 :city :state :zip]]]]
[:client [:id :name :code]]
]]]
payments (graphql/query identity (venia/graphql-query {:venia/queries (->graphql query)}) {:clients [ [:client/code (query-params "client-code")]]})]
[:client [:id :name :code]]]]]
payments (graphql/query identity (venia/graphql-query {:venia/queries (->graphql query)}) {:clients [[:client/code (query-params "client-code")]]})]
{:body
(list (:all-payments (:data payments)))})))
(defn export-sales [{:keys [query-params identity]}]
(assert-admin identity)
(statsd/time! [(str "export.time") {:tags #{(client-tag query-params)
@@ -153,7 +149,7 @@
[:line_items [:item_name :total :tax :discount :category]]
[:client [:id :name :code]]]]]
payments (graphql/query identity (venia/graphql-query {:venia/queries (->graphql query)}))
parsedouble #(some-> % Double/parseDouble) ]
parsedouble #(some-> % Double/parseDouble)]
{:body
(seq (map
(fn [s]
@@ -206,13 +202,11 @@
(update :total #(some-> % Double/parseDouble))))
(:all-expected-deposits (:data payments))))})))
(generate/add-encoder org.joda.time.DateTime
(fn [c jsonGenerator]
(.writeString jsonGenerator (str c))))
(defn export-clients[{:keys [identity]}]
(defn export-clients [{:keys [identity]}]
(assert-admin identity)
{:body (into []
(map <-graphql)
@@ -262,11 +256,10 @@
(-> v :vendor/address :address/city)
(-> v :vendor/address :address/state)
(-> v :vendor/address :address/zip)
(-> v (vendor/terms-for-client-id client) )
(-> v (vendor/terms-for-client-id client))
(-> v (vendor/account-for-client-id client) (accounts/clientize client) :account/name)
(-> v (vendor/account-for-client-id client) :account/numeric-code)
]
))
(-> v (vendor/account-for-client-id client) :account/numeric-code)]))
(into [["Vendor Name" "Address" "City" "State" "Zip" "Terms" "Account" "Account Code"]]))]
{:body
(into []
@@ -386,7 +379,7 @@
{:id (:db/id e)
:date (:transaction/date e)
:post_date (:transaction/post-date e)
:client { :code (:client/code client)
:client {:code (:client/code client)
:id (:db/id client)
:name (:client/name client)}
:amount (:transaction/amount e)
@@ -405,7 +398,6 @@
#_#_:original-id (Integer/parseInt (query-params "original"))
:count Integer/MAX_VALUE})]
{:body (map
(comp ->graphql
(fn [i]
@@ -459,10 +451,10 @@
(defn export-raw [{:keys [query-params identity]}]
(assert-admin identity)
(alog/info ::executing-query :q (get query-params "query" ))
(alog/info ::executing-query :q (get query-params "query"))
(statsd/time! [(str "export.time") {:tags #{"export:raw"}}]
{:body
(into (list) (apply dc/q (read-string (get query-params "query" )) (into [(dc/db conn)] (read-string (get query-params "args" "[]")))))}))
(into (list) (apply dc/q (read-string (get query-params "query")) (into [(dc/db conn)] (read-string (get query-params "args" "[]")))))}))
(defn export-ntg-account-snapshot [_]
(let [clients (->> (dc/q '[:find (pull ?e [:db/id :client/code :client/locations])
@@ -564,8 +556,7 @@
{[:charge/processor :xform iol-ion.query/ident] [:db/ident]}]
:sales-order/line-items [:order-line-item/item-name
:order-line-item/category
:order-line-item/total]}
]
:order-line-item/total]}]
:start [:sales-order/client+date [(:db/id client) (coerce/to-date date)]]
:end [:sales-order/client+date [(:db/id client) (coerce/to-date end)]]
:reverse false
@@ -576,40 +567,34 @@
(:db/id client))
(< (compare (:sales-order/date curr)
(coerce/to-date end))
0))
)))
]
0)))))]
entry all-entries
:let [sales-columns [(-> entry :sales-order/client :client/name)
(atime/unparse-local (coerce/from-date (-> entry :sales-order/date)) atime/standard-time)
(-> entry :sales-order/total)
(-> entry :sales-order/tip)
(-> entry :sales-order/service-charge)
(-> entry :sales-order/reference-link)
]
(-> entry :sales-order/reference-link)]
sales-column-count (count sales-columns)
tender-column-count 6]
row (concat [sales-columns]
(map (fn [tender]
(concat
(take sales-column-count (repeat nil))
[
(-> tender :charge/total)
[(-> tender :charge/total)
(-> tender :charge/tax)
(-> tender :charge/tip)
(-> tender :charge/type-name)
(some-> tender :charge/processor name)
(-> tender :charge/reference-link)
]))
(-> tender :charge/reference-link)]))
(:sales-order/charges entry))
(map (fn [tender]
(concat
(take (+ sales-column-count tender-column-count) (repeat nil))
[
(-> tender :order-line-item/item-name)
[(-> tender :order-line-item/item-name)
(-> tender :order-line-item/category)
(-> tender :order-line-item/total)
]))
(-> tender :order-line-item/total)]))
(:sales-order/line-items entry)))]
row
@@ -617,7 +602,7 @@
_ (when balance
(reset! last-used-value balance))
balance (or balance @last-used-value)]
[ l numeric-code (account->name a) date-str
[l numeric-code (account->name a) date-str
(format "%.2f" balance)])))}))
#_(export-ntg-payment-snapshot nil)
@@ -628,7 +613,6 @@
(handler request)
{:status 401})))
(def routes2 {"api/" {"sales/" {"aggregated/" {#"export/?" {:get :aggregated-sales-export}}
#"export/?" {:get :export-sales}
"ntg-export" {:get :export-ntg-sales-snapshot}}
@@ -660,10 +644,9 @@
:export-ntg-sales-snapshot (-> export-ntg-sales-snapshot wrap-csv-response
(wrap-schema-enforce :query-schema (mc/schema [:map
[:date {:required true
:decode/string #(try (atime/parse % atime/iso-date) (catch Exception _ nil))} :some]]) )
:decode/string #(try (atime/parse % atime/iso-date) (catch Exception _ nil))} :some]]))
(wrap-form-4xx-2 (fn [_] {:body "Invalid Date"}))
(wrap-predetermined-api-key "fd07755a-ed4c-4c9a-ad85-fbdd8af37206")
)
(wrap-predetermined-api-key "fd07755a-ed4c-4c9a-ad85-fbdd8af37206"))
:export-trial-balance (-> export-trial-balance wrap-csv-response wrap-secure)
:export-accounts (-> export-accounts wrap-json-response wrap-secure)
:export-transactions (-> export-transactions wrap-json-response wrap-secure)

View File

@@ -23,8 +23,6 @@
:else
{:status 404}))
(def routes {"api/" {"ezcater/" {#"event/?" :ezcater-event}}})
(def match->handler {:ezcater-event (-> handle-ezcater
wrap-json-params)})

View File

@@ -53,8 +53,8 @@
event-date (some-> (excel/xls-date->date event-date)
coerce/to-date-time
atime/as-local-time
coerce/to-date )]
(cond (and event-date client-id location )
coerce/to-date)]
(cond (and event-date client-id location)
[:order #:sales-order
{:date event-date
:external-id (str "ezcater/order/" client-id "-" location "-" order-number)

View File

@@ -11,9 +11,6 @@
[clojure.set :as set]
[datomic.api :as dc]))
(defn handle-graphql [{:keys [request-method query-params clients] :as r}]
(when (= "none" (:user/role (:identity r)))
(throw-unauthorized))
@@ -26,7 +23,7 @@
{:status 200
:body (pr-str (ql/query (:identity r) (if (= request-method :get) (query-params "query") body) (assoc variables
:clients
clients) ))
clients)))
:headers {"Content-Type" "application/edn"}})
(catch Throwable e
@@ -35,7 +32,7 @@
{:status 400
:body (pr-str result)
:headers {"Content-Type" "application/edn"}})
(if-let [message (:validation-error (ex-data (.getCause e)) )]
(if-let [message (:validation-error (ex-data (.getCause e)))]
(do
(alog/warn ::graphql-validation-error
:message message
@@ -48,6 +45,5 @@
:body (pr-str {:errors [{:message (str "Unhandled error:" (str e))}]})
:headers {"Content-Type" "application/edn"}}))))))
(def routes {"api/" {#"graphql/?" :graphql}})
(def match->handler {:graphql (wrap-secure handle-graphql)})

View File

@@ -97,7 +97,6 @@
invoice)
(defn admin-only-if-multiple-clients [is]
(let [client-count (->> is
(map :invoice/client)
@@ -318,8 +317,6 @@
:data (ex-data e)})
:headers {"Content-Type" "application/edn"}}))))
(defn bulk-account-overrides [{{files :file
files-2 "file"
client :client

View File

@@ -25,8 +25,6 @@
(csv/write-csv w %)
(.toString w))))))
(defn execute-query [query-params params]
(let [{:keys [query-id]} params]
(mu/with-context {:query-id query-id}
@@ -37,7 +35,6 @@
(into (list) (apply dc/q (edn/read-string query-string)
(into [(dc/db conn)] (edn/read-string (get query-params "args" "[]")))))))))
(defn put-query [guid body note & [lookup-key client]]
(let [id (pull-id (dc/db conn) [:saved-query/lookup-key lookup-key])
guid (if lookup-key
@@ -62,8 +59,6 @@
:csv-results-url (str "/api/queries/" guid "/results/csv")
:json-results-url (str "/api/queries/" guid "/results/json")}}))
(defn get-queries [{:keys [identity]}]
(assert-admin identity)
(let [obj (s3/list-objects :bucket-name (:data-bucket env)
@@ -77,7 +72,7 @@
(assert-admin identity)
(put-query (str (UUID/randomUUID)) (body-string request) (query-params "note")))
(defn get-query [{:keys [identity params]} ]
(defn get-query [{:keys [identity params]}]
(assert-admin identity)
(let [{:keys [query-id]} params
obj (s3/get-object :bucket-name (:data-bucket env)
@@ -89,7 +84,7 @@
:csv-results-url (str "/api/queries/" query-id "/results/csv")
:json-results-url (str "/api/queries/" query-id "/results/json")}}))
(defn update-query [{:keys [query-params identity params] :as request} ]
(defn update-query [{:keys [query-params identity params] :as request}]
(assert-admin identity)
(put-query (:query-id params) (body-string request) (query-params "note")))

View File

@@ -22,7 +22,7 @@
{:status 200
:headers {"Content-Type" "application/edn"}
:body (pr-str {:token token
:url (:yodlee2-fastlink env)}) }))
:url (:yodlee2-fastlink env)})}))
(defn refresh-provider-accounts [{:keys [identity edn-params]}]
(assert-admin identity)
(alog/info ::refreshing :params edn-params)
@@ -34,7 +34,7 @@
(:provider-account-id edn-params))
{:status 200
:headers {"Content-Type" "application/edn"}
:body "{}" }
:body "{}"}
(catch Exception e
(alog/error ::error :error e)
{:status 400
@@ -75,7 +75,7 @@
d-clients/get-by-id
:client/code)
(Long/parseLong id)
(dissoc data :client-id )))}
(dissoc data :client-id)))}
(catch Exception e
(alog/error ::error :error e)
{:status 500
@@ -93,7 +93,7 @@
(:provider-account-id edn-params))
{:status 200
:headers {"Content-Type" "application/edn"}
:body (pr-str {}) }
:body (pr-str {})}
(catch Exception e
(alog/error ::error :error e)
{:status 400
@@ -110,11 +110,11 @@
(def routes {"api" {"/yodlee2" {"/fastlink" :fastlink
"/provider-accounts/refresh/" :refresh-provider-accounts
["/provider-accounts/" :client "/" :id ] :get-provider-account-detail
["/reauthenticate/" :id ] :reauthenticate
["/provider-accounts/" :client "/" :id] :get-provider-account-detail
["/reauthenticate/" :id] :reauthenticate
"/provider-accounts/delete/" :delete-provider-account}}})
(def match->handler {:fastlink (-> fastlink wrap-secure (valid-for :get))
:refresh-provider-accounts (-> refresh-provider-accounts wrap-secure (valid-for :post))
:get-provider-account-detail (-> get-provider-account-detail wrap-secure (valid-for :get))
:reauthenticate (-> reauthenticate wrap-secure (valid-for :post))
:delete-provider-account (-> delete-provider-account wrap-secure (valid-for :post))} )
:delete-provider-account (-> delete-provider-account wrap-secure (valid-for :post))})

View File

@@ -8,7 +8,7 @@
:transaction-rule/dom-gte :transaction-rule/dom-lte
:transaction-rule/amount-gte :transaction-rule/amount-lte
:transaction-rule/client :transaction-rule/bank-account
:transaction-rule/yodlee-merchant]} ]
:transaction-rule/yodlee-merchant]}]
(let [transaction-dom (some-> transaction
:transaction/date
.toInstant
@@ -80,8 +80,6 @@
(recur rules)))
[])))
(defn group-rules-by-priority [rules]
(->> rules
(map (fn [r] (update r :transaction-rule/description #(some-> % ->pattern))))
@@ -150,7 +148,7 @@
(fn [transaction valid-locations]
(if (:transaction/payment transaction)
transaction
(let [matching-rules (get-matching-rules-by-priority rules-by-priority transaction )]
(let [matching-rules (get-matching-rules-by-priority rules-by-priority transaction)]
(if-let [top-match (and (= (count matching-rules) 1) (first matching-rules))]
(apply-rule transaction top-match valid-locations)
transaction))))))

View File

@@ -33,7 +33,6 @@
(.addShutdownHook (Runtime/getRuntime)
(Thread. f)))
(defn gzip-handler []
(let [gz (GzipHandler.)]
(doto gz

View File

@@ -123,7 +123,6 @@
"vendor_id" (-> i :payment/vendor :db/id)
"type" "payment"}))
(defprotocol SolrClient
(index-documents-raw [this index xs])
(index-documents [this index xs])
@@ -158,12 +157,11 @@
(query [this index q]
(-> (client/post (str (url/url solr-uri "solr" index "query"))
{:body (json/write-str q )
{:body (json/write-str q)
:socket-timeout 30000
:connection-timeout 30000
:headers {"Content-Type" "application/json"}
:as :json}
)
:as :json})
:body
:response
:docs))
@@ -191,11 +189,7 @@
(def impl (if (= :solr (:solr-impl env))
(->RealSolrClient (:solr-uri env))
(->MockSolrClient )))
(->MockSolrClient)))
(defn touch-with-ledger [i]
(index-documents impl "invoices" [i [:journal-entry/original-entity i]]))
@@ -205,7 +199,6 @@
([i index]
(index-documents impl index [i])))
(defrecord InMemSolrClient [data-set-atom]
SolrClient
(index-documents [this index xs]

View File

@@ -27,11 +27,9 @@
"Authorization" (str "Bearer " (:client/square-auth-token client))
"Content-Type" "application/json"}))
(defn ->square-date [d]
(f/unparse (f/formatter "YYYY-MM-dd'T'HH:mm:ssZZ") d))
(def manifold-api-stream
(let [stream (s/stream 100)]
(->> stream
@@ -104,7 +102,6 @@
:exception error))
[]))))
(def item-cache (atom {}))
(defn fetch-catalog [client i v]
@@ -124,13 +121,11 @@
#(do (swap! item-cache assoc i %)
%))))
(defn fetch-catalog-cache [client i version]
(if (get @item-cache i)
(de/success-deferred (get @item-cache i))
(fetch-catalog client i version)))
(defn item->category-name-impl [client item version]
(capture-context->lc
(cond (:item_id (:item_variation_data item))
@@ -161,7 +156,6 @@
:item item)
"Uncategorized"))))
(defn item-id->category-name [client i version]
(capture-context->lc
(-> [client i]
@@ -226,7 +220,6 @@
(concat (:orders result) continued-results))))
(:orders result)))))))
(defn search
([client location start end]
(capture-context->lc
@@ -250,11 +243,9 @@
(concat (:orders result) continued-results))))
(:orders result))))))))
(defn amount->money [amt]
(* 0.01 (or (:amount amt) 0.0)))
;; to get totals:
(comment
(reduce
@@ -415,7 +406,6 @@
:client client
:location location)))))))
(defn get-payment [client p]
(de/chain (manifold-api-call
{:url (str "https://connect.squareup.com/v2/payments/" p)
@@ -424,7 +414,6 @@
:body
:payment))
(defn continue-payout-entry-list [c l poi cursor]
(capture-context->lc lc
(de/chain
@@ -618,7 +607,6 @@
:count (count x))
@(dc/transact-async conn x))))))))
(defn upsert-payouts
([client]
(apply de/zip
@@ -667,7 +655,6 @@
(log/info ::done-loading-refunds)))))))
(defn get-cash-shift [client id]
(de/chain (manifold-api-call {:url (str (url/url "https://connect.squareup.com/v2/cash-drawers/shifts" id))
:method :get
@@ -826,8 +813,6 @@
d1
d2))
(defn remove-voided-orders
([client]
(apply de/zip
@@ -865,29 +850,24 @@
@(dc/transact-async conn x)))))
(de/catch (fn [e]
(log/warn ::couldnt-remove :error e)
nil) ))))))
nil)))))))
#_(comment
(require 'auto-ap.time-reader)
@(let [[c [l]] (get-square-client-and-location "DBFS") ]
(log/peek :x [ c l])
(search c l #clj-time/date-time "2026-03-28" #clj-time/date-time "2026-03-29")
@(let [[c [l]] (get-square-client-and-location "DBFS")]
(log/peek :x [c l])
(search c l #clj-time/date-time "2026-03-28" #clj-time/date-time "2026-03-29"))
)
@(let [[c [l]] (get-square-client-and-location "NGAK") ]
(log/peek :x [ c l])
@(let [[c [l]] (get-square-client-and-location "NGAK")]
(log/peek :x [c l])
(remove-voided-orders c l #clj-time/date-time "2024-04-11" #clj-time/date-time "2024-04-15"))
(doseq [c (get-square-clients)]
(try
@(remove-voided-orders c)
(catch Exception e
nil)))
)
nil))))
(defn upsert-all [& clients]
(capture-context->lc
@@ -956,8 +936,6 @@
[:clients clients]
@(apply upsert-all clients)))
(comment
(defn refunds-raw-cont
([client l cursor so-far]
@@ -987,7 +965,6 @@
(->>
@(let [[c [l]] (get-square-client-and-location "NGGG")]
(search c l (time/now) (time/plus (time/now) (time/days -1))))
(filter (fn [r]
@@ -997,7 +974,6 @@
(->>
@(let [[c [l]] (get-square-client-and-location "NGGG")]
(refunds-raw-cont c l nil []))
(filter (fn [r]
(str/starts-with? (:created_at r) "2024-03-14")))))
@@ -1032,12 +1008,7 @@
[(:client/code c) (atime/unparse-local (clj-time.coerce/to-date-time (:sales-order/date bad-row)) atime/normal-date) (:sales-order/total bad-row) (:sales-order/tax bad-row) (:sales-order/tip bad-row) (:db/id bad-row)])
:separator \tab)
;; =>
;; =>
(require 'auto-ap.time-reader)
@@ -1046,26 +1017,15 @@
(clojure.pprint/pprint (let [[c [l]] (get-square-client-and-location "NGVT")]
l
(def z @(search c l #clj-time/date-time "2025-02-23T00:00:00-08:00"
#clj-time/date-time "2025-02-28T00:00:00-08:00"))
(take 10 (map #(first (deref (order->sales-order c l %))) z)))
)
(take 10 (map #(first (deref (order->sales-order c l %))) z))))
(->> z
(filter (fn [o]
(seq (filter (comp #{"OTHER"} :type) (:tenders o)))))
(filter #(not (:name (:source %))))
(count)
)
(count))
(doseq [[code] (seq (dc/q '[:find ?code
:in $
@@ -1075,32 +1035,22 @@
[?o :sales-order/client ?c]
[?c :client/code ?code]]
(dc/db conn)))
:let [[c [l]] (get-square-client-and-location code)
]
:let [[c [l]] (get-square-client-and-location code)]
order @(search c l #clj-time/date-time "2026-01-01T00:00:00-08:00" (time/now))
:when (= "Invoices" (:name (:source order) ))
:when (= "Invoices" (:name (:source order)))
:let [[sales-order] @(order->sales-order c l order)]]
(when (should-import-order? order)
(println "DATE IS" (:sales-order/date sales-order))
(when (some-> (:sales-order/date sales-order) coerce/to-date-time (time/after? #clj-time/date-time "2026-2-16T00:00:00-08:00"))
(println "WOULD UPDATE" sales-order)
@(dc/transact auto-ap.datomic/conn [sales-order])
)
#_@(dc/transact )
(println "DONE"))
)
@(dc/transact auto-ap.datomic/conn [sales-order]))
#_@(dc/transact)
(println "DONE")))
#_(filter (comp #{"OTHER"} :type) (mapcat :tenders z))
@(let [[c [l]] (get-square-client-and-location "NGRY")]
#_(search c l (clj-time.coerce/from-date #inst "2025-02-28") (clj-time.coerce/from-date #inst "2025-03-01"))
(order->sales-order c l (:order (get-order c l "KdvwntmfMNTKBu8NOocbxatOs18YY" )))
)
)
(order->sales-order c l (:order (get-order c l "KdvwntmfMNTKBu8NOocbxatOs18YY")))))

View File

@@ -24,7 +24,7 @@
:account/invoice-allowance [:db/ident]
:account/client-overrides [:db/id
:account-client-override/name
{:account-client-override/client [:db/id :client/name]}]} ])
{:account-client-override/client [:db/id :client/name]}]}])
(defn search- [id query client]
(let [client-part (if (some->> client (can-see-client? id))

View File

@@ -35,9 +35,8 @@
tx-instant)))
(group-by (fn hours-ago [d]
(time/in-hours (time/interval (coerce/to-date-time d) (time/now)))
))
)]
(time/in-hours (time/interval (coerce/to-date-time d) (time/now))))))]
(for [h (range 24)]
(count (tx-lookup h [])))))
@@ -59,8 +58,7 @@
[:div
[:div {:class "w-full h-64"
:id "client-chart"
:data-chart (hx/json {
:labels ["2 years ago" "1 year ago" "today"],
:data-chart (hx/json {:labels ["2 years ago" "1 year ago" "today"],
:series [(for [n [2 1 0]
:let [start (time/plus (time/now) (time/years (- n)))]]
(->> (dc/q '[:find (count ?c)
@@ -80,19 +78,14 @@
[:div
[:div {:class "w-full h-64"
:id "changes"
:data-chart (hx/json {
:labels (for [n (range -24 0)]
:data-chart (hx/json {:labels (for [n (range -24 0)]
(format "%d" n)),
:series [(hourly-changes)]})}]
[:script {:lang "javascript"}
(hiccup/raw
"new Chartist.Line('#changes', JSON.parse(document.getElementById('changes').getAttribute('data-chart')))")]]]])]
)
"Admin")
)
"new Chartist.Line('#changes', JSON.parse(document.getElementById('changes').getAttribute('data-chart')))")]]]])])
"Admin"))
(def key->handler
{
:auto-ap.routes.admin/page (wrap-client-redirect-unauthenticated (wrap-admin page))
})
{:auto-ap.routes.admin/page (wrap-client-redirect-unauthenticated (wrap-admin page))})

View File

@@ -121,7 +121,7 @@
(some->> query-params :type)
(merge-query {:query {:find []
:in ['?r]
:where ['[?e :account/type ?r] ]}
:where ['[?e :account/type ?r]]}
:args [(some->> query-params :type)]})
true
@@ -213,8 +213,7 @@
(map (fn [client]
(format "'%s'" (pull-attr (dc/db conn)
:client/name
(-> client)))
) %)))
(-> client)))) %)))
:form-params form-params)) ;; TODO shouldnt need to bubble this through. See if we can eliminate the passing of form and last-form.
)
{:keys [tempids]} (audit-transact [[:upsert-entity (cond-> entity
@@ -278,14 +277,13 @@
(defn dialog* [{:keys [entity form-params form-errors]}]
(fc/start-form form-params form-errors
[:div {:x-data (hx/json {"accountName" (or (:account/name form-params) (:account/numeric-code entity))
"accountCode" (or (:account/numeric-code form-params) (:account/numeric-code entity) )})
:hx-target "this"
}
"accountCode" (or (:account/numeric-code form-params) (:account/numeric-code entity))})
:hx-target "this"}
(com/modal
{}
[:form (-> {:hx-ext "response-targets"
:hx-swap "outerHTML swap:300ms"
:hx-target-400 "#form-errors .error-content" }
:hx-target-400 "#form-errors .error-content"}
(assoc (if (:db/id entity)
:hx-put
:hx-post)
@@ -381,7 +379,7 @@
(com/validated-save-button {:errors (seq form-errors)}
"Save account")])]])]))
(defn new-client-override [{ {:keys [index]} :query-params}]
(defn new-client-override [{{:keys [index]} :query-params}]
(html-response
(fc/start-form-with-prefix
[:account/client-overrides (or index 0)]
@@ -416,9 +414,6 @@
{})
:form-errors form-errors})))
(def key->handler
(apply-middleware-to-all-handlers
(->>

View File

@@ -36,7 +36,6 @@
(sort-by :created-at)
reverse))
(defn is-background-job?
"This function checks whether a given task is a background job.
It does this by checking the environment of the task's container definitions for an environment variable
@@ -60,7 +59,7 @@
(defn job-exited-successfully? [task]
(if (= 0 (->> task
:containers
(filter (comp #{"integreat-app" } :name))
(filter (comp #{"integreat-app"} :name))
(first)
:exit-code))
true
@@ -85,7 +84,7 @@
(filter is-background-job?)
(map ecs-task->job))]
[jobs (count jobs)]))
(def query-schema (mc/schema [:map ]))
(def query-schema (mc/schema [:map]))
(def grid-page
(helper/build {:id "job-table"
@@ -107,8 +106,7 @@
:entity-name "Job"
:query-schema query-schema
:route :admin-job-table
:headers [
{:key "start"
:headers [{:key "start"
:name "Start"
:render #(some-> % :start-date (atime/unparse-local atime/standard-time))}
{:key "end"
@@ -150,7 +148,7 @@
:network-configuration {:aws-vpc-configuration {:subnets ["subnet-5e675761" "subnet-8519fde2" "subnet-89bab8d4"]
:security-groups ["sg-004e5855310c453a3" "sg-02d167406b1082698"]
:assign-public-ip AssignPublicIp/ENABLED}}}
args (assoc-in [:overrides :container-overrides ] [{:name "integreat-app" :environment [{:name "args" :value (pr-str args)}]}]))))
args (assoc-in [:overrides :container-overrides] [{:name "integreat-app" :environment [{:name "args" :value (pr-str args)}]}]))))
(defn job-start [{:keys [form-params]}]
(if (not (get (currently-running-jobs) (:name form-params)))
@@ -174,20 +172,18 @@
[:pre.text-xs.mr-1 "s3://data.prod.app.integreatconsult.com/bulk-import/"]
(com/text-input {:placeholder "ledger-data.csv"
:name (fc/field-name)
:value (fc/field-value)} )]))]
:value (fc/field-value)})]))]
(= "register-invoice-import" name)
[
(fc/with-field :invoice-url
[(fc/with-field :invoice-url
(com/validated-field {:label "Url"
:errors (fc/field-errors)}
[:div.flex.place-items-center.gap-2
[:pre.text-xs.mr-1 "s3://data.prod.app.integreatconsult.com/bulk-import/"]
(com/text-input {:placeholder "invoice-data.csv"
:name (fc/field-name)
:value (fc/field-value)} )]))]
:value (fc/field-value)})]))]
(= "load-historical-sales" name)
[
(fc/with-field :client
[(fc/with-field :client
(com/validated-field {:label "Client"
:errors (fc/field-errors)}
(com/typeahead {:name (fc/field-name)
@@ -200,13 +196,10 @@
:errors (fc/field-errors)}
(com/text-input {:placeholder "60"
:name (fc/field-name)
:value (fc/field-value)} )))]
:else nil))
:value (fc/field-value)})))]
:else nil)))
)
(defn subform [{{:keys [name]} :query-params }]
(defn subform [{{:keys [name]} :query-params}]
(html-response
(fc/start-form {} nil
(subform* {:name name}))))
@@ -245,7 +238,7 @@
:hx-target "#sub-form"
:hx-swap "innerHTML"})))
[:div#sub-form (subform* {:name (fc/with-field :name (fc/field-value))}) ]]
[:div#sub-form (subform* {:name (fc/with-field :name (fc/field-value))})]]
[:div
(com/form-errors {:errors (:errors fc/*form-errors*)})
@@ -256,8 +249,7 @@
[:ledger-url {:optional true} [:string {:min 1}]]
[:invoice-url {:optional true} [:string {:min 1}]]
[:client {:optional true} entity-id]
[:days {:optional true} [:int {:min 1 :max 120}]]
]))
[:days {:optional true} [:int {:min 1 :max 120}]]]))
(def key->handler
(apply-middleware-to-all-handlers

View File

@@ -47,7 +47,6 @@
(:import
[java.util UUID]))
;; TODO make more reusable malli schemas, use unions if it would be helpful
;; TODO copy save logic from graphql version
;; TODO cash drawer shift
@@ -67,8 +66,6 @@
[:enum
"" "all" "only-mine"]]]]]))
(defn filters [request]
[:form {"hx-trigger" "change delay:500ms, keyup changed from:.hot-filter delay:1000ms"
"hx-get" (bidi/path-for ssr-routes/only-routes
@@ -178,7 +175,6 @@
:where ['[?e :client/groups ?g]]}
:args [(clojure.string/upper-case (:group query-params))]})
(not (str/blank? (some-> query-params :code)))
(merge-query {:query {:in ['?code]
:where ['[?e :client/code ?code]]}
@@ -293,8 +289,6 @@
(def row* (partial helper/row* grid-page))
(def bank-account-schema [:and [:map
[:db/id [:or entity-id temp-id]]
[:bank-account/name :string]
@@ -443,10 +437,6 @@
[:client/week-b-credits {:optional true} [:maybe :double]]
[:client/week-b-debits {:optional true} [:maybe :double]]]))
(defn email-contact-row [email-contact-cursor]
(com/data-grid-row
(-> {:x-data (hx/json {:show (boolean (not (fc/field-value (:new? email-contact-cursor))))})
@@ -526,12 +516,10 @@
(com/data-grid-cell {:class "align-top"}
(com/a-icon-button {"@click.prevent.stop" "$refs.p.remove()"} svg/x))))
(defn- dialog-header [step]
[:div.flex [:div.p-2 (mm/step-name step)] [:p.ml-2.rounded.bg-gray-50.p-2.dark:bg-gray-600
[:span {:x-text "clientName"}]]])
(defrecord InfoModal [linear-wizard]
mm/ModalWizardStep
(step-name [_]
@@ -598,7 +586,6 @@
(mm/default-step-footer linear-wizard this :validation-route ::route/navigate)
:validation-route ::route/navigate)))
(defn match-row [_]
(com/data-grid-row
{:x-ref "p"
@@ -644,8 +631,6 @@
(com/data-grid-cell {:class "align-top"}
(com/a-icon-button {"@click.prevent.stop" "show=false; setTimeout(() => $refs.p.remove(), 500)"} svg/x))))
(defrecord MatchesModal [linear-wizard]
mm/ModalWizardStep
(step-name [_]
@@ -699,7 +684,6 @@
(step-key [_]
:contact)
(edit-path [_ _]
[])
@@ -798,7 +782,6 @@
:to (mm/encode-step-key [:bank-account (fc/field-value (:db/id bank-account))])})}
svg/pencil)]])])
(defmulti bank-account-card (comp deref :bank-account/type))
(defmethod bank-account-card :bank-account-type/cash [bank-account]
(bank-account-card-base {:bg-color "bg-green-50"
@@ -821,7 +804,6 @@
:icon svg/check
:bank-account bank-account}))
(defmulti bank-account-form (comp deref :bank-account/type))
(defmethod bank-account-form :bank-account-type/cash [bank-account]
[:div
@@ -904,8 +886,6 @@
:checked (fc/field-value)}
"Visible for payment"))]])
(defn- plaid-account-select [client-id]
(fc/with-field :bank-account/plaid-account
(com/validated-field {:errors (fc/field-errors)
@@ -1048,7 +1028,6 @@
[:div#days-indicator
(i/days-ago* (some-> (fc/field-value)))]])
(fc/with-field :bank-account/include-in-reports
(com/checkbox {:name (fc/field-name)
:value (boolean (fc/field-value))
@@ -1224,8 +1203,6 @@
(yodlee-account-select (:db/id (:snapshot fc/*form-data*)))
(intuit-account-select (:db/id (:snapshot fc/*form-data*)))])
(defn new-bank-account-card []
[:div {:class "w-[30em]"}
(com/card {:class "w-full border-dotted bg-gray-50"}
@@ -1255,7 +1232,6 @@
(edit-path [_ _] [])
(step-schema [_]
(mut/select-keys (mm/form-schema linear-wizard) #{}))
@@ -1284,7 +1260,6 @@
:validation-route ::route/navigate)]
:validation-route ::route/navigate)))
(defn square-location-table []
[:div#square-locations
[:div.htmx-indicator
@@ -1367,7 +1342,7 @@
:hx-include "#square-token"
:hx-trigger "click"
:hx-indicator "#square-locations"
:hx-target "#square-locations" }
:hx-target "#square-locations"}
"Refresh")]
(fc/with-field :client/square-locations
@@ -1447,8 +1422,6 @@
(filterv #(not= (get-in multi-form-state [:step-params :db/id]) (:db/id %)) bank-accounts)))
(mm/select-state [] nil))))
(defrecord CashFlowModal [linear-wizard]
mm/ModalWizardStep
(step-name [_]
@@ -1663,7 +1636,6 @@
#(mm/select-state % [] {})
#(assoc-in % [:snapshot :client/bank-accounts] new-bank-accounts)))))))
(def sales-summary-query
"[:find ?d4 (sum ?total) (sum ?tax) (sum ?tip) (sum ?service-charge) (sum ?discount) (sum ?returns)
:with ?s
@@ -1792,9 +1764,6 @@
[?cds :cash-drawer-shift/opened-cash ?opened-cash]
[(iol-ion.query/excel-date ?date) ?d4]]")
(defn setup-sales-queries-impl [client-id]
(let [{client-code :client/code feature-flags :client/feature-flags} (dc/pull (dc/db conn) '[:client/code :client/feature-flags] client-id)
is-new-square? ((set feature-flags) "new-square")]
@@ -1840,7 +1809,6 @@
(cheshire/generate-string (format (slurp (io/resource which)) url)))}
children))
(defn biweekly-sales-powerquery [request]
(setup-sales-queries-impl (:db/id (:route-params request)))
(modal-response
@@ -1872,7 +1840,6 @@
(com/modal-footer {} [:div])))))
(def key->handler
(apply-middleware-to-all-handlers
{::route/page (helper/page-route grid-page)

View File

@@ -38,7 +38,6 @@
invoice)
(defn reset-id [i]
(update i :invoice-number
(fn [n] (if (re-matches #"#+" n)
@@ -85,7 +84,6 @@
(get (by (comp :db/id :vendor-schedule-payment-dom/client) :vendor-schedule-payment-dom/dom (:vendor/schedule-payment-dom vendor))
client-id))
(defn invoice-rows->transaction [rows user]
(->> rows
(mapcat (fn [{:keys [vendor-id total client-id date invoice-number default-location check automatically-paid-when-due account-id]}]
@@ -121,8 +119,7 @@
(let [[[bank-account]] (seq (dc/q '[:find ?ba
:in $ ?c
:where [?c :client/bank-accounts ?ba]
[?ba :bank-account/type :bank-account-type/cash]
]
[?ba :bank-account/type :bank-account-type/cash]]
(dc/db conn)
client-id))]
[:upsert-transaction #:transaction {:amount (- (:invoice/total invoice))
@@ -130,18 +127,17 @@
:client (:invoice/client invoice)
:status "POSTED"
:bank-account bank-account
:db/id #_ {:clj-kondo/ignore [:unresolved-var]} (digest/sha-256 transaction-id)
:id #_ {:clj-kondo/ignore [:unresolved-var]} (digest/sha-256 transaction-id)
:db/id #_{:clj-kondo/ignore [:unresolved-var]} (digest/sha-256 transaction-id)
:id #_{:clj-kondo/ignore [:unresolved-var]} (digest/sha-256 transaction-id)
:raw-id transaction-id
:vendor (:invoice/vendor invoice)
:description-original "Cash payment"
:date (coerce/to-date date)
:approval-status :transaction-approval-status/approved
:accounts [{:db/id (str #_ {:clj-kondo/ignore [:unresolved-var]} (digest/sha-256 transaction-id) "-account")
:accounts [{:db/id (str #_{:clj-kondo/ignore [:unresolved-var]} (digest/sha-256 transaction-id) "-account")
:transaction-account/account (:db/id (a/get-account-by-numeric-code-and-sets 21000 ["default"]))
: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))
account-id)]
(some-> payment remove-nils)
@@ -158,10 +154,9 @@
(dc/q '[:find ?n ?v
:in $ [?n ...]
:where [?v :vendor/name ?n]]
(dc/db conn)
)
(dc/db conn))
(into {}))
all-clients (merge (into {}(dc/q '[:find ?n (pull ?v [:db/id :client/locations])
all-clients (merge (into {} (dc/q '[:find ?n (pull ?v [:db/id :client/locations])
:in $
:where [?v :client/name ?n]]
(dc/db conn)))
@@ -226,8 +221,7 @@
(com/validated-field {:label "Tab-separated invoices"
:errors (fc/field-errors)}
[:textarea {:class (hh/add-class "w-full h-96" inputs/default-input-classes) :placeholder (hiccup/raw sample)
:name (fc/field-name)
}
:name (fc/field-name)}
(fc/field-value)]))
(com/form-errors {:errors (:errors fc/*form-errors*)})
(com/validated-save-button {:color :primary
@@ -275,7 +269,7 @@
"@mouseover" "show=true"
"@mouseout" "show=false"
"x-tooltip" "{content: ()=>$refs.tooltip.innerHTML ,
allowHTML: true}" }
allowHTML: true}"}
(format "%d vendors not found" (count (:vendors-not-found result))))
[:template {:x-ref "tooltip"}
@@ -309,8 +303,7 @@
::route/import (-> import
(wrap-schema-enforce :form-schema [:map [:tsv :string]])
(wrap-nested-form-params)
(wrap-form-4xx-2 form))
})
(wrap-form-4xx-2 form))})
(fn [h]
(-> h
(wrap-admin)

View File

@@ -59,7 +59,6 @@
:else
(pr-str v)))
(defn inspect [{{:keys [entity-id]} :params :as request}]
(alog/info ::inspect
:request request)
@@ -187,6 +186,5 @@
(if entity-id
(result-table {:entity-id entity-id})
[:div#history-table])
[:div#inspector]
])
[:div#inspector]])
"History")))

View File

@@ -72,9 +72,9 @@
(defn fetch-ids [db request]
(let [query-params (:query-params request)
query (cond-> {:query {:find []
:in '[$ ]
:in '[$]
:where '[]}
:args [db ]}
:args [db]}
(:sort query-params) (add-sorter-fields {"source" ['[?e :import-batch/source ?s]
'[?s :db/ident ?s2]
'[(name ?s2) ?sort-source]]

View File

@@ -42,7 +42,7 @@
(def query-schema (mc/schema
[:maybe
(into [:map {}
[:vendor {:optional true :default nil} [:maybe [:entity-map {:pull [:db/id :vendor/name]}]]] ]
[:vendor {:optional true :default nil} [:maybe [:entity-map {:pull [:db/id :vendor/name]}]]]]
default-grid-fields-schema)]))
(defn filters [request]
[:form {"hx-trigger" "change delay:500ms, keyup changed from:.hot-filter delay:1000ms"
@@ -154,7 +154,7 @@
(not (str/blank? (:client-group query-params)))
(merge-query {:query {:in ['?client-group]
:where ['[?e :transaction-rule/client-group ?client-group] ]}
:where ['[?e :transaction-rule/client-group ?client-group]]}
:args [(clojure.string/upper-case (:client-group query-params))]})
true
@@ -288,10 +288,6 @@
[:transaction-rule/bank-account]
:form-params form-params)))
(def transaction-read '[{:transaction/client [:client/name]
:transaction/bank-account [:bank-account/name]}
:transaction/description-original
@@ -369,8 +365,6 @@
'[(>= ?dom ?dom-gte)]]}
:args [dom-gte]})
true
(merge-query {:query {:where ['[?e :transaction/id]]}}))
results (->>
@@ -505,7 +499,6 @@
(com/data-grid-cell {:class "align-top"}
(com/a-icon-button {"@click.prevent.stop" "show=false; setTimeout(() => $refs.p.remove(), 500)"} svg/x))))
(defn all-ids-not-locked [all-ids]
(->> all-ids
(dc/q '[:find ?t
@@ -1003,7 +996,7 @@
{}))))})
(fn [h]
(-> h
(wrap-copy-qp-pqp)
(wrap-copy-qp-pqp)
(wrap-apply-sort grid-page)
(wrap-merge-prior-hx)
(wrap-schema-enforce :query-schema query-schema)

View File

@@ -41,7 +41,7 @@
(into [:map {}
[:name {:optional true :default nil} [:maybe [:string {:string/decode strip}]]]
#_[:role {:optional true} [:maybe (ref->enum-schema "user-role")]]
#_[:client {:optional true :default nil} [:maybe [:entity-map {:pull [:db/id :client/name]}]]] ]
#_[:client {:optional true :default nil} [:maybe [:entity-map {:pull [:db/id :client/name]}]]]]
default-grid-fields-schema)]))
(defn filters [request]
[:form {"hx-trigger" "change delay:500ms, keyup changed from:.hot-filter delay:1000ms"
@@ -203,8 +203,6 @@
(def row* (partial helper/row* grid-page))
(def table* (partial helper/table* grid-page))
(defn merge-submit [{:keys [form-params request-method identity] :as request}]
(if (= (:source-vendor form-params)
(:target-vendor form-params))
@@ -245,7 +243,6 @@
(= i (dec (count steps))) (assoc :last? true))
n)))))
;; TODO add plaid merchant
;; TODO each client only used once
@@ -285,7 +282,6 @@
(com/data-grid-cell {:class "align-top"}
(com/a-icon-button {"@click.prevent.stop" "show=false; setTimeout(() => $refs.p.remove(), 500)"} svg/x)))))
(defn automatically-paid-when-due-row [terms-override-cursor]
(com/data-grid-row
(-> {:x-data (hx/json {:show (boolean (not (fc/field-value (:new? terms-override-cursor))))})
@@ -303,15 +299,12 @@
:value (fc/field-value)
:value-fn :db/id
:content-fn #(pull-attr (dc/db conn) :client/name (:db/id %))
:size :small})))
(com/data-grid-cell {:class "align-top"}
(com/a-icon-button {"@click.prevent.stop" "show=false; setTimeout(() => $refs.p.remove(), 500)"} svg/x)))))
(defn- account-typeahead*
[{:keys [name value client-id x-model]}]
[:div.flex.flex-col
@@ -370,12 +363,6 @@
(com/data-grid-cell {:class "align-top"}
(com/a-icon-button {"@click.prevent.stop" "show=false; setTimeout(() => $refs.p.remove(), 500)"} svg/x))))))
(defn dialog* [{:keys [entity form-params form-errors] :as params}]
(alog/peek ::dialog-entity form-params)
(fc/start-form form-params form-errors
@@ -868,7 +855,6 @@
(def vendor-wizard (->VendorWizard :info))
(def key->handler
(apply-middleware-to-all-handlers
(->>
@@ -921,7 +907,7 @@
(fn [cursor _] (account-override-row cursor)))})
(fn [h]
(-> h
(wrap-copy-qp-pqp)
(wrap-copy-qp-pqp)
(wrap-apply-sort grid-page)
(wrap-merge-prior-hx)
(wrap-schema-enforce :query-schema query-schema)

View File

@@ -14,7 +14,6 @@
:headers {"Location" "/login"}
:session {}})
(defn impersonate [request]
{:status 200
:session {:identity (dissoc (jwt/unsign (get-in request [:query-params "jwt"])
@@ -39,21 +38,20 @@
next (assoc "state" (hu/url-encode next))))))))
(defn- page-contents [request]
[:div#app { "@notification.document" "notificationDetails=event.detail.value; showNotification=true"
[:div#app {"@notification.document" "notificationDetails=event.detail.value; showNotification=true"
:x-data (hx/json {:showError false
:errorDetails ""
:showNotification false
:notificationDetails ""})
"@htmx:response-error.camel" "errorDetails = $event.detail.xhr.response; showError=true;"
}
"@htmx:response-error.camel" "errorDetails = $event.detail.xhr.response; showError=true;"}
[:div#app-contents.flex.overflow-hidden
[:div#main-content {:class "relative w-full h-full overflow-y-auto px-4 bg-gray-100 dark:bg-gray-900 min-h-content " }
[:div#main-content {:class "relative w-full h-full overflow-y-auto px-4 bg-gray-100 dark:bg-gray-900 min-h-content "}
[:div#notification-holder
[:div.fixed.top-0.right-0.left-0.z-30.mx-auto.max-w-screen-lg.w-screen-lg.my-0.pt-8.rounded-lg {:x-show "showNotification" }
[:div.fixed.top-0.right-0.left-0.z-30.mx-auto.max-w-screen-lg.w-screen-lg.my-0.pt-8.rounded-lg {:x-show "showNotification"}
[:div.relative
[:button.absolute.right-2.top-2.w-6.h-6.z-50.text-blue-400
{ "@click" "showNotification=false"}
{"@click" "showNotification=false"}
svg/filled-x]]
[:div.m-4.overflow-auto.z-30.flex.center-items.justify-center.text-blue-800.bg-blue-50.dark:bg-gray-800.dark:text-blue-400.border-blue-300.rounded-lg.border.max-h-96
@@ -73,7 +71,7 @@
[:div.fixed.top-0.right-0.left-0.z-30.mx-auto.max-w-screen-lg.w-screen-lg.my-0.pt-8.rounded-lg
[:div.relative
[:button.absolute.right-2.top-2.w-6.h-6.z-50.text-red-600
{ "@click" "showError=false"}
{"@click" "showError=false"}
svg/filled-x]]
[:div.m-4.overflow-auto.z-30.flex.center-items.justify-center.text-red-800.bg-red-50.dark:bg-gray-800.dark:text-red-400.border-red-300.rounded-lg.border.max-h-96
@@ -94,10 +92,9 @@
[:div.p-4
[:img {:src "/img/logo-big.png"}]
[:div
[:div
[:a.button.is-large.is-primary {:href (login-url (get (:query-params request) "redirect-to"))} "Login with Google"]]
"HELLO"])
]]] ])
"HELLO"])]]]])
(defn login [request]
(base-page

View File

@@ -2,7 +2,6 @@
(:require [auto-ap.ssr.form-cursor :as fc]
[auto-ap.ssr.utils :refer [html-response wrap-schema-enforce]]))
(defn add-new-entity-handler
([path render-fn] (add-new-entity-handler path
render-fn

View File

@@ -33,8 +33,7 @@
(com/content-card {:class " w-[748px]"
:hx-target "this"
:hx-swap "outerHTML"}
[:div.col-span-1.p-4 {:class "p-4 sm:p-6 space-y-4 overflow-visible "
}
[:div.col-span-1.p-4 {:class "p-4 sm:p-6 space-y-4 overflow-visible "}
[:h3 {:class "mb-4 text-xl font-semibold dark:text-white"}
"Signature"]
[:div#signature-notification.notification.block {:style {:display "none"}}]
@@ -58,7 +57,6 @@
:x-show "existing && !editing"}])
[:canvas.rounded.rounded-lg.border.border-gray-300
{:style {:width 696
:height 261}
:x-init "signature= new SignaturePad($el); signature.off()"
@@ -67,7 +65,6 @@
:height 261
:x-show "existing ? editing: true"}]]
[:div.flex.gap-2.justify-end
(com/button {:color :primary
:x-show "!editing"
@@ -92,13 +89,12 @@
#_#_:hx-target "#signature-notification"
:hx-swap "outerHTML"
:id "upload"
:hx-trigger "z"
}
[:div.htmx-indicator
:hx-trigger "z"}
[:div.htmx-indicator
[:div.bg-gray-100.flex.items-center.text-green-500.justify-center.rounded.rounded-lg.border.border-gray-400 {:style {:width "696px" :height "261px"}}
(svg/spinner {:class "w-4 h-4 text-primary-300"})
[:div.ml-3 "Loading..."]]]
[:div.htmx-indicator-hidden
[:div.htmx-indicator-hidden
[:div.border-2.border-dashed.rounded-lg.p-4.w-full.text-center.cursor-pointer.h-64.flex.items-center.justify-center.text-lg.relative
{:x-data (hx/json {"files" nil
"hovering" false})
@@ -111,8 +107,6 @@
'text-green-700': hovering
}"}
[:input {:type "file"
:name "file"
:class "absolute inset-0 m-0 p-0 w-full h-full outline-none opacity-0",
@@ -126,8 +120,7 @@
[:template {:x-for "f in files"}
[:li (com/pill {:color :primary :x-text "f.name"})]]]]
[:div.htmx-indicator-hidden "Drop a signature file (696x261 pixels jpeg) here."]]]] ]]])))
[:div.htmx-indicator-hidden "Drop a signature file (696x261 pixels jpeg) here."]]]]]]])))
(defn upload-signature-data [{{:strs [signatureData]} :form-params client :client :as request}]
(let [prefix "data:image/png;base64,"]
@@ -149,9 +142,9 @@
(defn upload-signature-file [{{:strs [signatureData]} :form-params client :client user :identity :as request}]
(assert-can-see-client user client)
(let [{:strs [file]} (:multipart-params request) ]
(try
(let [signature-id (str (UUID/randomUUID)) ]
(let [{:strs [file]} (:multipart-params request)]
(try
(let [signature-id (str (UUID/randomUUID))]
(s3/put-object :bucket-name "integreat-signature-images" #_(:data-bucket env)
:key (str signature-id ".jpg")
:input-stream (io/input-stream (:tempfile file))
@@ -276,7 +269,6 @@
(def search (wrap-json-response search))
(defn bank-account-search [{:keys [route-params query-params clients]}]
(let [valid-client-ids (set (map :db/id clients))
selected-client-id (Long/parseLong (get route-params :db/id))

View File

@@ -24,7 +24,7 @@
(def query-schema (mc/schema
[:maybe
(into [:map {} ]
(into [:map {}]
default-grid-fields-schema)]))
(def vendor-read '[:db/id
@@ -49,7 +49,7 @@
:in $ ?c ?v
:where
[?p :payment/client ?c]
[?p :payment/date ?d ]
[?p :payment/date ?d]
[(>= ?d #inst "2025-01-01T08:00")]
[(< ?d #inst "2026-01-01T08:00")]
[?p :payment/type :payment-type/check]
@@ -68,7 +68,7 @@
:in $ [?c ...] vendor-read
:where
[?p :payment/client ?c]
[?p :payment/date ?d ]
[?p :payment/date ?d]
[(>= ?d #inst "2025-01-01T08:00")]
[(< ?d #inst "2026-01-01T08:00")]
[?p :payment/type :payment-type/check]
@@ -81,7 +81,7 @@
(filter (fn [[_ _ a]]
(>= (or a 0.0) 600.0)))
(sort-by (fn [[client _ amount]]
[(:client/code client ) amount]))
[(:client/code client) amount]))
(into []))
paginated (apply-pagination-raw {:start (:start query-params)
:per-page (:per-page query-params)} all)]
@@ -129,8 +129,7 @@
(com/pill
{:class "text-xs font-medium"
:color :primary}
(str/capitalize t99-type))
)])}
(str/capitalize t99-type)))])}
{:key "tin"
:name "TIN"
:sort-key "tin"
@@ -143,8 +142,7 @@
(when-let [tin-type (some-> vendor :vendor/legal-entity-tin-type :db/ident name)]
(com/pill {:class "text-xs font-medium"
:color :yellow}
(name tin-type)))]
)}
(name tin-type)))])}
{:key "expense-account"
:name "Expense Account"
:show-starting "md"
@@ -152,7 +150,7 @@
[:div.flex.gap-4
(when-let [tin (-> vendor :vendor/default-account :account/name)]
[:span {:class "text-xs font-medium py-0.5 "}
tin]) ])}
tin])])}
{:key "address"
:name "Address"
:sort-key "address"
@@ -176,8 +174,6 @@
:color :primary}
"Paid $" (Math/round paid)))}]}))
(def table* (partial helper/table* grid-page))
(def row* (partial helper/row* grid-page))
@@ -185,7 +181,6 @@
{:keys [vendor-id]} :route-params
{:keys [client-id]} :query-params}]
(assert-can-see-client identity client-id)
@(dc/transact conn [[:upsert-entity (-> form-params
@@ -198,20 +193,18 @@
(:address/zip a)
(:db/id a))
a
nil)) ))]])
nil))))]])
(html-response
(row* identity [(dc/pull (dc/db conn) [:db/id :client/code] client-id)
(dc/pull (dc/db conn) vendor-read vendor-id)
(sum-for-client-vendor client-id vendor-id)
] {:flash? true})
(sum-for-client-vendor client-id vendor-id)] {:flash? true})
:headers {"hx-trigger" "modalclose"
"hx-retarget" (format "#entity-table tr[data-id=\"%d\"]" vendor-id)}))
(def default-vendor-read '[* {[:vendor/legal-entity-1099-type :xform iol-ion.query/ident] [:db/ident]
[:vendor/legal-entity-tin-type :xform iol-ion.query/ident] [:db/ident]}])
(def form-schema (mc/schema [:map
[:vendor/address {:default {}}
[:maybe
@@ -221,7 +214,7 @@
[:address/street2 {:optional true} [:maybe [:string {:decode/string strip}]]]
[:address/city {:optional true} [:maybe [:string {:decode/string strip}]]]
[:address/state {:optional true} [:maybe [:string {:decode/string strip}]]]
[:address/zip {:optional true} [:maybe [:re { :error/message "invalid zip"
[:address/zip {:optional true} [:maybe [:re {:error/message "invalid zip"
:decode/string strip} #"^(\d{5}|)$"]]]]]]
[:vendor/legal-entity-name {:optional true} [:maybe [:string {:decode/string strip}]]]
[:vendor/legal-entity-first-name {:optional true} [:maybe [:string {:decode/string strip}]]]

View File

@@ -26,7 +26,7 @@
[malli.core :as mc]))
(def query-schema (mc/schema
[:maybe
(into [:map {} ]
(into [:map {}]
default-grid-fields-schema)]))
(def default-read '[:db/id
@@ -37,7 +37,7 @@
{:plaid-item/accounts [:db/id
{:bank-account/_plaid-account [{:bank-account/integration-status
[{ [ :integration-status/state :xform iol-ion.query/ident] [:db/ident]}
[{[:integration-status/state :xform iol-ion.query/ident] [:db/ident]}
:integration-status/message
:integration-status/last-attempt
:integration-status/last-updated]}]}
@@ -66,7 +66,6 @@
true (apply-sort-3 query-params)
true (apply-pagination query-params))))
(defn hydrate-results [ids db _]
(let [results (pull-many-by-id db default-read ids)]
(->> ids
@@ -78,15 +77,12 @@
[(hydrate-results ids-to-retrieve db request)
matching-count]))
(defn plaid-link-script [token]
(format "window.plaid = Plaid.create(
{ token: \"%s\",
onSuccess: function (x) { htmx.trigger(\"#link-account\", \"linked\", {\"public_token\": x})}
})", token))
(defn link [{{client-code "client_code" public-token "public_token"} :form-params
:keys [identity]
:as request}]
@@ -99,9 +95,9 @@
(alog/info ::linking-plaid :id identity :client-code client-code)
(assert-can-see-client identity (pull-attr (dc/db conn) :db/id [:client/code client-code]))
(let [access-token (:access_token (p/exchange-public-token public-token client-code))
account-result (p/get-accounts access-token )
account-result (p/get-accounts access-token)
item {:plaid-item/client [:client/code client-code]
:plaid-item/external-id (-> account-result :item :item_id )
:plaid-item/external-id (-> account-result :item :item_id)
:plaid-item/access-token access-token
:plaid-item/status (or (some-> account-result :item :error)
"SUCCESS")
@@ -141,7 +137,6 @@
(com/button-icon {} svg/refresh)
"Start relink")])))
(def grid-page
(helper/build
{:id "plaid-table"
@@ -211,7 +206,6 @@
(when bad-integration
" (detail)")
(when bad-integration
[:template {:x-ref "tooltip"}
[:div.text-red-700
@@ -237,19 +231,16 @@
[:li [:svg.inline {:data-jdenticon-value (:db/id a) :width "24" :height "24"}] (:plaid-account/name a) " - " (:plaid-account/number a) " - updated "
(atime/unparse-local (:plaid-account/last-synced a) atime/normal-date)])])}]}))
(def page (helper/page-route grid-page))
(def table (helper/table-route grid-page))
(def key->handler
(apply-middleware-to-all-handlers
{
:company-plaid page
{:company-plaid page
:company-plaid-table table
:company-plaid-link link
:company-plaid-relink relink
:company-plaid-relink relink}
}
(fn [h]
(-> h
(wrap-copy-qp-pqp)

View File

@@ -32,8 +32,7 @@
[:maybe clj-date-schema]]
[:end-date {:optional true}
[:maybe clj-date-schema]]
[:client {:optional true :default nil} [:maybe [:entity-map {:pull [:db/id :client/name]}]]]
]
[:client {:optional true :default nil} [:maybe [:entity-map {:pull [:db/id :client/name]}]]]]
default-grid-fields-schema)]))
(def default-read '[:db/id :report/client [:report/created :xform clj-time.coerce/from-date] :report/url :report/name :report/creator])
@@ -45,13 +44,11 @@
:where '[[?e :report/client ?c]]}
:args [db (:trimmed-clients request)]}
(:sort query-params) (add-sorter-fields {"client" ['[?e :report/client ?c]
'[?c :client/name ?sort-client]]
"created" ['[?e :report/created ?sort-created]]
"creator" ['[?e :report/creator ?sort-creator]]
"name" ['[?e :report/name ?sort-name]
]}
"name" ['[?e :report/name ?sort-name]]}
query-params)
true
@@ -115,7 +112,7 @@
:sort-key "creator"
:render (fn [report]
(when (:report/creator report)
(com/pill {:color :primary }
(com/pill {:color :primary}
(:report/creator report))))}
{:key "created"
:name "Created"
@@ -147,7 +144,6 @@
{:flash? true
:delete-after-settle? true}))))
(def key->handler
(apply-middleware-to-all-handlers
(->>
@@ -159,7 +155,7 @@
(into company-reconciliation-report/key->handler))
(fn [h]
(-> h
(wrap-copy-qp-pqp)
(wrap-copy-qp-pqp)
(wrap-apply-sort grid-page)
(wrap-merge-prior-hx)
(wrap-schema-enforce :query-schema query-schema)

View File

@@ -43,13 +43,13 @@
(:vendor-id (:query-params request))
(merge-query {:query '{:in [?v]
:where [ [?e :invoice/vendor ?v]]}
:args [ (:db/id (:vendor-id (:query-params request)))]})
:where [[?e :invoice/vendor ?v]]}
:args [(:db/id (:vendor-id (:query-params request)))]})
(:account-id (:query-params request))
(merge-query {:query '{:in [?a]
:where [ [?iea :invoice-expense-account/account ?a]]}
:args [ (:db/id (:account-id (:query-params request)))]}))]
:where [[?iea :invoice-expense-account/account ?a]]}
:args [(:db/id (:account-id (:query-params request)))]}))]
(dc/query query)))
@@ -57,7 +57,7 @@
(let [start (:start-date (:query-params request) (time/plus (time/now) (time/days -30)))
end (:end-date (:query-params request) (time/now))
query (cond-> {:query '{:find [?cn ?vn (sum ?t)]
:with [ ?e]
:with [?e]
:in [$ [?clients ?start ?end]]
:where
[[(iol-ion.query/scan-invoices $ ?clients ?start ?end) [[?e _ ?sort-default] ...]]
@@ -66,8 +66,7 @@
[?e :invoice/total ?t]
[?e :invoice/vendor ?v]
[?v :vendor/name ?vn]
[?c :client/name ?cn]
]}
[?c :client/name ?cn]]}
:args
[(dc/db conn)
[(extract-client-ids (:clients request)
@@ -86,7 +85,6 @@
end (time/minus starting (time/weeks (dec n)))]]
[(atime/as-local-time (coerce/to-date-time start)) (atime/as-local-time (coerce/to-date-time end))]))))
(defn- best-week [d weeks]
(reduce
(fn [acc [start end]]
@@ -97,7 +95,6 @@
nil
weeks))
(defn expense-breakdown-card* [request]
(com/card {:class "w-full h-full" :id "expense-breakdown-report"}
[:div {:class "flex flex-col px-8 py-8 space-y-3 w-full h-full"}
@@ -186,7 +183,7 @@
[:div {:class "flex flex-col px-8 py-8 space-y-3"}
[:div
[:h1.text-2xl.mb-3.font-bold "Invoice totals by vendor"]
[:form {:hx-get (bidi.bidi/path-for ssr-routes/only-routes :company-expense-report-invoice-total-card )
[:form {:hx-get (bidi.bidi/path-for ssr-routes/only-routes :company-expense-report-invoice-total-card)
:hx-trigger "change"
:hx-target "#invoice-totals-report"
:hx-swap "outerHTML"}
@@ -201,7 +198,7 @@
(com/date-input {:name (fc/field-name)
:class "w-64"
:value (some-> (fc/field-value)
(atime/unparse-local atime/normal-date)) })]))
(atime/unparse-local atime/normal-date))})]))
(fc/with-field :end-date
(com/validated-field {:label "End"
:errors (fc/field-errors)}
@@ -209,13 +206,12 @@
(com/date-input {:name (fc/field-name)
:class "w-64"
:value (some-> (fc/field-value)
(atime/unparse-local atime/normal-date)) })]))])]
(atime/unparse-local atime/normal-date))})]))])]
[:div {:class "overflow-scroll min-w-full max-h-[700px]"}
(let [data (lookup-invoice-total-data request)
companies (sort (set (map first data)))
vendors (sort (set (map second data)))
result (by (juxt first second) last data)
]
result (by (juxt first second) last data)]
(com/data-grid
{:headers (into
[(com/data-grid-header {:class "sticky left-0 z-60 bg-gray-100"} "Vendor")]
@@ -231,7 +227,7 @@
(com/data-grid-cell
{}
(or (some->> (get result [company vendor])
(format "$%,.2f" ))
(format "$%,.2f"))
[:span.text-gray-200 "-"])))))))]]]))
(defn page [request]

View File

@@ -53,7 +53,7 @@
(com/data-grid-cell {:class class}
(when (> (count (:missing-transactions row)) 0)
[:div
(com/button { :x-tooltip.on.click "{content: ()=>$refs.tooltip.innerHTML, theme: 'light', allowHTML: true}" }
(com/button {:x-tooltip.on.click "{content: ()=>$refs.tooltip.innerHTML, theme: 'light', allowHTML: true}"}
[:div.flex.gap-2.items-center
(count (:missing-transactions row))
[:div.w-4.h-4 svg/question]])
@@ -67,7 +67,6 @@
(com/data-grid-cell {}
(format "$%,.2f" (:transaction/amount r))))))]]))))))])
(defn reconciliation-card* [{:keys [request report]}]
(com/content-card {:class "w-full" :id "reconciliation-report"}
[:div {:class "flex flex-col px-8 py-8 space-y-3"}
@@ -88,7 +87,7 @@
(com/date-input {:name (fc/field-name)
:class "w-64"
:value (some-> (fc/field-value)
(atime/unparse-local atime/normal-date)) })]))
(atime/unparse-local atime/normal-date))})]))
(fc/with-field :end-date
(com/validated-field {:label "End"
:errors (fc/field-errors)}
@@ -96,12 +95,11 @@
(com/date-input {:name (fc/field-name)
:class "w-64"
:value (some-> (fc/field-value)
(atime/unparse-local atime/normal-date)) })]))
(atime/unparse-local atime/normal-date))})]))
(com/button {:color :primary :class "self-center w-24"} "Run")])]
(if report
(if report
(report* {:request request :report report})
[:div "Please choose a time range to run the report"])
]]))
[:div "Please choose a time range to run the report"])]]))
(defn page [request]
(base-page
@@ -134,7 +132,7 @@
url/map->query))
(defn get-report-data [start-date end-date client-ids]
(let [client-codes (map first (dc/q '[:find ?cc :in $ [?c ...] :where [?c :client/code ?cc]] (dc/db conn ) client-ids))]
(let [client-codes (map first (dc/q '[:find ?cc :in $ [?c ...] :where [?c :client/code ?cc]] (dc/db conn) client-ids))]
(for [[ib ba c] (seq (apply get-intuit-bank-accounts (dc/db conn) client-codes))
:let [raw-transactions (get-transactions (atime/unparse-local start-date atime/iso-date)
(atime/unparse-local end-date atime/iso-date)
@@ -169,7 +167,7 @@
:requires-feedback-count (:transaction-approval-status/requires-feedback found-transactions 0)
:missing-transactions missing-transactions})))
(defn card [{ {:keys [start-date end-date]} :query-params :as request}]
(defn card [{{:keys [start-date end-date]} :query-params :as request}]
(let [client-ids (extract-client-ids (:clients request)
(:client-id request)
(when (:client-code request)
@@ -191,4 +189,4 @@
[:start-date {:optional true}
[:maybe clj-date-schema]]
[:end-date {:optional true}
[:maybe clj-date-schema]] ])))))
[:maybe clj-date-schema]]])))))

View File

@@ -35,7 +35,7 @@
(def query-schema (mc/schema
[:maybe
(into [:map {}
[:client-id {:optional true} [:maybe entity-id]] ]
[:client-id {:optional true} [:maybe entity-id]]]
default-grid-fields-schema)]))
(defn fetch-ids [db request]
@@ -46,7 +46,6 @@
'[?e :yodlee-provider-account/client ?xx]]}
:args [db (:trimmed-clients request)]}
(:sort query-params) (add-sorter-fields {"status" ['[?e :yodlee-provider-account/status ?sort-status]]
"client" ['[?e :yodlee-provider-account/client ?c]
'[?c :client/code ?sort-client]]
@@ -54,7 +53,7 @@
"last-updated" ['[?e :yodlee-provider-account/last-updated ?sort-last-updated]]}
query-params)
true
(merge-query {:query {:find ['?e ]
(merge-query {:query {:find ['?e]
:where ['[?e :yodlee-provider-account/id]]}}))]
(->> query
@@ -62,7 +61,6 @@
(apply-sort-3 query-params)
(apply-pagination query-params))))
(defn hydrate-results [ids db _]
(let [results (->> (pull-many db default-read ids)
(group-by :db/id))]
@@ -70,21 +68,19 @@
(map results)
(map first))))
(defn fetch-page [request]
(let [db (dc/db conn)
{ids-to-retrieve :ids matching-count :count} (fetch-ids db request)]
[(->> (hydrate-results ids-to-retrieve db request))
matching-count]))
(defn fastlink-dialog [{:keys [client]}]
(modal-response
(com/modal
{}
(com/modal-card
{}
[:div.flex [:div.p-2 "Yodlee Fastlink"] ]
[:div.flex [:div.p-2 "Yodlee Fastlink"]]
[:div
[:div#fa-spot]
[:script {:lang "text/javascript"}
@@ -100,8 +96,7 @@ fastlink.open({fastLinkURL: '%s',
}},
'fa-spot');
" (:yodlee2-fastlink env) (yodlee/get-access-token (:client/code client))))]
]
" (:yodlee2-fastlink env) (yodlee/get-access-token (:client/code client))))]]
[:div]))))
(defn reauthenticate [{:keys [form-params identity]}]
@@ -113,7 +108,7 @@ fastlink.open({fastLinkURL: '%s',
{}
(com/modal-card
{}
[:div.flex [:div.p-2 "Yodlee Fastlink"] ]
[:div.flex [:div.p-2 "Yodlee Fastlink"]]
[:div
[:div#fa-spot]
[:script {:lang "text/javascript"}
@@ -168,8 +163,7 @@ fastlink.open({fastLinkURL: '%s',
(when-not (:client request)
[:div.text-xs "Note: please select a specific customer to link a new account."])]])
:row-buttons (fn [request _]
[
(com/button {:hx-put (bidi/path-for ssr-routes/only-routes
[(com/button {:hx-put (bidi/path-for ssr-routes/only-routes
:company-yodlee-provider-account-reauthenticate)
:color :primary
:hx-target "#modal-holder"}
@@ -195,7 +189,7 @@ fastlink.open({fastLinkURL: '%s',
:render #(when-let [status (:yodlee-provider-account/status %)]
(com/pill {:color (if (not= status "SUCCESS")
:yellow
:primary) }
:primary)}
status))}
{:key "detailed-status"
:name "Detailed Status"
@@ -230,14 +224,11 @@ fastlink.open({fastLinkURL: '%s',
provider-account
{:flash? true}))))
(def key->handler
(apply-middleware-to-all-handlers
{
:company-yodlee page
{:company-yodlee page
:company-yodlee-table table
:company-yodlee-fastlink-dialog fastlink-dialog
}
:company-yodlee-fastlink-dialog fastlink-dialog}
(fn [h]
(-> h
(wrap-copy-qp-pqp)

Some files were not shown because too many files have changed in this diff Show More