refactor(charts): unify on Chart.js, remove Chartist #10

Closed
notid wants to merge 139 commits from integreat-unify-charts into master
210 changed files with 8694 additions and 9627 deletions
Showing only changes of commit ba87805d4c - Show all commits

View File

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

View File

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

View File

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

View File

@@ -16,6 +16,6 @@
(-> [] (-> []
(into (map (fn [i] (if is-component? (into (map (fn [i] (if is-component?
[:db/retractEntity i] [: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] [:db/add e a i]) new-rels))
(into (map (fn [i] [:upsert-entity i]) vs))))) (into (map (fn [i] [:upsert-entity i]) vs)))))

View File

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

View File

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

View File

@@ -7,8 +7,7 @@
(fn [m k v] (fn [m k v]
(if (not (nil? v)) (if (not (nil? v))
(assoc m k v) (assoc m k v)
m m))
))
{} {}
m)] m)]
(if (seq result) (if (seq result)
@@ -49,25 +48,22 @@
:journal-entry/line-items (into [(cond-> {:db/id (str raw-invoice-id "-" 0) :journal-entry/line-items (into [(cond-> {:db/id (str raw-invoice-id "-" 0)
:journal-entry-line/account :account/accounts-payable :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))) 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))))] (not credit-invoice?) (assoc :journal-entry-line/credit (Math/abs (:invoice/total entity))))]
(map-indexed (fn [i ea] (map-indexed (fn [i ea]
(cond-> (cond->
{:db/id (str raw-invoice-id "-" (inc i)) {:db/id (str raw-invoice-id "-" (inc i))
:journal-entry-line/account (:db/id (:invoice-expense-account/account ea)) :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))) 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))))) (not credit-invoice?) (assoc :journal-entry-line/debit (Math/abs (:invoice-expense-account/amount ea)))))
(:invoice/expense-accounts entity))) (:invoice/expense-accounts entity)))
:journal-entry/cleared (and (< (:invoice/outstanding-balance entity) 0.01) :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] (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 [[date]] (seq (dc/q '[:find ?ti :in $ ?tx
:where [?tx :db/txInstant ?ti]] :where [?tx :db/txInstant ?ti]]
db 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]}]) (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] (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 [[date]] (seq (dc/q '[:find ?ti :in $ ?tx
:where [?tx :db/txInstant ?ti]] :where [?tx :db/txInstant ?ti]]
db db
@@ -51,7 +50,7 @@
(let [extant-entry (or (when-let [original-entity (:journal-entry/original-entity ledger-entry)] (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])) (dc/pull db extant-read [:journal-entry/original-entity original-entity]))
(when-let [external-id (:journal-entry/external-id ledger-entry)] (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-> (cond->
[[:upsert-entity (into (-> ledger-entry [[: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-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)) 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) (when (and (seq line-items)
(= (Math/round (* 1000 total-debits)) (= (Math/round (* 1000 total-debits))
(Math/round (* 1000 total-credits)))) (Math/round (* 1000 total-credits))))
@@ -65,6 +64,5 @@ _ (clojure.pprint/pprint [total-debits total-credits])
(concat (concat
[[:db/retractEntity [:journal-entry/original-entity (:db/id summary)]]] [[:db/retractEntity [:journal-entry/original-entity (:db/id summary)]]]
(when client-id [{:db/id client-id (when client-id [{:db/id client-id
:client/ledger-last-change (current-date db)}])))))) :client/ledger-last-change (current-date db)}]))))))

View File

@@ -81,7 +81,6 @@
[[:upsert-ledger journal-entry]] [[:upsert-ledger journal-entry]]
[[:db/retractEntity [:journal-entry/original-entity (:db/id transaction)]]])))) [[:db/retractEntity [:journal-entry/original-entity (:db/id transaction)]]]))))
#_(comment #_(comment
;; If transactions are failing, it is likely that there are multiple bank accounts linked ;; If transactions are failing, it is likely that there are multiple bank accounts linked
@@ -148,6 +147,4 @@
[:upsert-ledger my-journal]]) [: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 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))) xs)))
(defn pull-many [db read ids ] (defn pull-many [db read ids]
(->> (dc/q '[:find (pull ?e r) (->> (dc/q '[:find (pull ?e r)
:in $ [?e ...] r] :in $ [?e ...] r]
db db
@@ -27,8 +27,7 @@
(fn [m k v] (fn [m k v]
(if (not (nil? v)) (if (not (nil? v))
(assoc m k v) (assoc m k v)
m m))
))
{} {}
m)] m)]
(if (seq result) (if (seq result)

File diff suppressed because one or more lines are too long

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -40,7 +40,6 @@
(merge-query {:query {:find ['?e] (merge-query {:query {:find ['?e]
:where ['[?e :import-batch/date]]}}))] :where ['[?e :import-batch/date]]}}))]
(cond->> (query2 query) (cond->> (query2 query)
true (apply-sort-3 args) true (apply-sort-3 args)
true (apply-pagination args)))) true (apply-pagination args))))
@@ -66,7 +65,6 @@
(map #(update % :import-batch/date coerce/to-date-time))) (map #(update % :import-batch/date coerce/to-date-time)))
matching-count :data args))) matching-count :data args)))
(defn attach [schema] (defn attach [schema]
(-> (->
(merge-with merge schema (merge-with merge schema
@@ -83,9 +81,7 @@
:count {:type 'Int} :count {:type 'Int}
:total {:type 'Int} :total {:type 'Int}
:start {:type 'Int} :start {:type 'Int}
:end {:type 'Int}}} :end {:type 'Int}}}}
}
:queries {:import_batch_page {:type :import_batch_page :queries {:import_batch_page {:type :import_batch_page
:args {:filters {:type :import_batch_filters}} :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 ")")] (let [error (str "Expense account total (" expense-account-total ") does not equal invoice total (" total ")")]
(throw (ex-info error {:validation-error error})))))) (throw (ex-info error {:validation-error error}))))))
(defn add-invoice [context {{:keys [expense_accounts client_id vendor_id] :as in} :invoice} _] (defn add-invoice [context {{:keys [expense_accounts client_id vendor_id] :as in} :invoice} _]
(assert-no-conflicting in) (assert-no-conflicting in)
(assert-can-see-client (:id context) client_id) (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) (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."})))) (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} _] (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] (mu/trace ::validating-invoice [:invoice in]
(do (do
@@ -261,7 +257,6 @@
(-> (d-invoices/get-by-id id) (->graphql (:id context))))) (-> (d-invoices/get-by-id id) (->graphql (:id context)))))
(defn get-ids-matching-filters [args] (defn get-ids-matching-filters [args]
(let [ids (some-> args (let [ids (some-> args
:filters :filters
@@ -448,8 +443,6 @@
[])] [])]
accounts))) accounts)))
(defn bulk-change-invoices [context args _] (defn bulk-change-invoices [context args _]
(assert-admin (:id context)) (assert-admin (:id context))
(when-not (:client_id args) (when-not (:client_id args)

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -13,7 +13,7 @@
[iol-ion.utils :refer [remove-nils]])) [iol-ion.utils :refer [remove-nils]]))
(defn get-intuit-bank-accounts (defn get-intuit-bank-accounts
( [db] ([db]
(dc/q '[:find ?external-id ?ba ?c (dc/q '[:find ?external-id ?ba ?c
:in $ :in $
:where :where
@@ -32,7 +32,6 @@
db db
client-codes))) client-codes)))
(defn intuit->transaction [transaction] (defn intuit->transaction [transaction]
(let [check-number (when (not (str/blank? (:Num transaction))) (let [check-number (when (not (str/blank? (:Num transaction)))
(try (try
@@ -46,7 +45,6 @@
:transaction/status "POSTED"} :transaction/status "POSTED"}
check-number (assoc :transaction/check-number check-number)))) check-number (assoc :transaction/check-number check-number))))
(defn intuits->transactions [transactions bank-account-id client-id] (defn intuits->transactions [transactions bank-account-id client-id]
(->> transactions (->> transactions
(map intuit->transaction) (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-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/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/deftest intuits->transactions
(t/testing "should give unique ids to duplicates" (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" (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] [clojure.data.csv :as csv]
[datomic.api :as dc])) [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]) (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] (defn tabulate-data [data]
@@ -48,7 +46,7 @@
transactions (->> transactions transactions (->> transactions
(map (fn [t] (map (fn [t]
(manual->transaction t bank-account-code->bank-account bank-account-code->client))) (manual->transaction t bank-account-code->bank-account bank-account-code->client)))
(t/apply-synthetic-ids ))] (t/apply-synthetic-ids))]
(try (try
(doseq [transaction transactions] (doseq [transaction transactions]
(when-not (seq (:errors transaction)) (when-not (seq (:errors transaction))

View File

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

View File

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

View File

@@ -95,5 +95,4 @@
nil) nil)
(Thread/sleep 10000))))) (Thread/sleep 10000)))))
(def import-yodlee2 (allow-once import-yodlee2-int)) (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 base-url "https://sandbox-quickbooks.api.intuit.com/v3")
(def prod-client-id "ABFRwAiOqQiLN66HKplXfyRE3ipD390DHsrUquflRCiOa81mxa") (def prod-client-id "ABFRwAiOqQiLN66HKplXfyRE3ipD390DHsrUquflRCiOa81mxa")
(def prod-client-secret "xDUj04GeQXpLvrhxep1jjDYwjJWbzzOPrirUQTKF") (def prod-client-secret "xDUj04GeQXpLvrhxep1jjDYwjJWbzzOPrirUQTKF")
@@ -27,11 +26,8 @@
;; "accessToken":, ;; "accessToken":,
;; ;;
(def prod-company-id "123146163906404") (def prod-company-id "123146163906404")
(def prod-base-url "https://quickbooks.api.intuit.com/v3") (def prod-base-url "https://quickbooks.api.intuit.com/v3")
(defn set-access-token [t] (defn set-access-token [t]
@@ -53,7 +49,6 @@
:bucket-name "data.prod.app.integreatconsult.com" :bucket-name "data.prod.app.integreatconsult.com"
:key "intuit/refresh-token"))))) :key "intuit/refresh-token")))))
#_{:clj-kondo/ignore [:clojure-lsp/unused-public-var]} #_{:clj-kondo/ignore [:clojure-lsp/unused-public-var]}
(defn init-tokens [access refresh] (defn init-tokens [access refresh]
(set-access-token access) (set-access-token access)
@@ -74,10 +69,9 @@
(defn get-basic-auth [] (defn get-basic-auth []
(Base64/encodeBase64String (.getBytes (str prod-client-id ":" prod-client-secret)))) (Base64/encodeBase64String (.getBytes (str prod-client-id ":" prod-client-secret))))
(defn get-fresh-access-token [] (defn get-fresh-access-token []
(let [refresh-token (lookup-refresh-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" {:headers {"Accept" "application/json"
"Content-Type" "application/x-www-form-urlencoded" "Content-Type" "application/x-www-form-urlencoded"
@@ -99,16 +93,15 @@
:as :json}) :as :json})
(defn get-bank-accounts-raw [token] (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 {:headers
(with-auth prod-base-headers token) (with-auth prod-base-headers token)
:as :json :as :json
:query-params {"query" "SELECT * From Account maxresults 1000"}})) :query-params {"query" "SELECT * From Account maxresults 1000"}}))
:QueryResponse)) :QueryResponse))
(defn get-bank-accounts [token] (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 {:headers
(with-auth prod-base-headers token) (with-auth prod-base-headers token)
:as :json :as :json
@@ -124,7 +117,6 @@
:last-updated (c/to-date-time (-> metadata :LastUpdatedTime)) :last-updated (c/to-date-time (-> metadata :LastUpdatedTime))
:current-balance (try (double current-balance) (catch Exception _ nil))})))) :current-balance (try (double current-balance) (catch Exception _ nil))}))))
(defn get-all-transactions [start end] (defn get-all-transactions [start end]
(let [token (get-fresh-access-token)] (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) (: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]}] (defn line->id [{:keys [source id client-code]}]
(str client-code "-" source "-" id)) (str client-code "-" source "-" id))
(defn csv->graphql-rows [lines] (defn csv->graphql-rows [lines]
(for [lines (partition-by line->id (drop 1 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)]] :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 (mapv (fn [[i]] {:db/id i
:invoice/outstanding-balance 0.0 :invoice/outstanding-balance 0.0
:invoice/status :invoice-status/paid})) :invoice/status :invoice-status/paid}))))
))
(alog/info ::closed :count (count invoices-to-close)))) (alog/info ::closed :count (count invoices-to-close))))

View File

@@ -1,7 +1,7 @@
(ns auto-ap.jobs.core (ns auto-ap.jobs.core
(:require [auto-ap.utils :refer [heartbeat]] (:require [auto-ap.utils :refer [heartbeat]]
[mount.core :as mount] [mount.core :as mount]
[auto-ap.datomic :refer [conn ]] [auto-ap.datomic :refer [conn]]
[auto-ap.logging :as alog] [auto-ap.logging :as alog]
[nrepl.server :refer [start-server]] [nrepl.server :refer [start-server]]
[auto-ap.background.metrics :refer [metrics-setup container-tags container-data logging-context]] [auto-ap.background.metrics :refer [metrics-setup container-tags container-data logging-context]]
@@ -14,7 +14,7 @@
(mu/trace ::execute-background-job (mu/trace ::execute-background-job
[] []
(try (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)) (start-server :port 9000 :bind "0.0.0.0" #_#_:handler (cider-nrepl-handler))
((heartbeat f name)) ((heartbeat f name))
(alog/info ::stopping :job 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>") :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)}}}))) :text (str "<div>You can download the original email here: " target-url)}}})))
(defn process-sqs [] (defn process-sqs []
(alog/info ::fetching-sqs) (alog/info ::fetching-sqs)
(doseq [message (:messages (sqs/receive-message {:queue-url (:invoice-import-queue-url env) (doseq [message (:messages (sqs/receive-message {:queue-url (:invoice-import-queue-url env)
@@ -79,27 +78,20 @@
(defn -main [& _] (defn -main [& _]
(execute "import-uploaded-invoices" process-sqs)) (execute "import-uploaded-invoices" process-sqs))
(comment (comment
(with-open [i (io/output-stream "/tmp/bryce.pdf")] (with-open [i (io/output-stream "/tmp/bryce.pdf")]
(clojure.java.io/copy (clojure.java.io/copy
(-> (s3/get-object :bucket-name (:data-bucket env) (-> (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) :input-stream)
i)) i))
(parse/parse-file "/tmp/bryce.pdf" "/tmp/bryce.pdf") (parse/parse-file "/tmp/bryce.pdf" "/tmp/bryce.pdf")
(-> (clojure.java.shell/sh "pdftotext" "-layout" "/tmp/bryce.pdf" "-") (-> (clojure.java.shell/sh "pdftotext" "-layout" "/tmp/bryce.pdf" "-")
:out :out)
)
1 1
(user/init-repl) (user/init-repl))
)

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -44,7 +44,6 @@
(dc/db conn) (dc/db conn)
50000)))) 50000))))
(def ^:dynamic bucket-name (:data-bucket env)) (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"]) (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
first))) first)))
(defn read-sysco-csv [k] (defn read-sysco-csv [k]
(-> (s3/get-object {:bucket-name bucket-name (-> (s3/get-object {:bucket-name bucket-name
:key k}) :key k})
@@ -84,11 +82,9 @@
(fn [acc row] (fn [acc row]
(update acc (get-line-account (nth row item-name-index)) (update acc (get-line-account (nth row item-name-index))
(fnil + 0.0) (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") items-with-tax (update items (get-line-account "TAX")
(fnil + 0.0) (fnil + 0.0)
tax) tax)
@@ -153,9 +149,9 @@
:client/locations] :client/locations]
(:db/id matching-client)) (:db/id matching-client))
location-hint location-hint
location-hint ) location-hint)
:date (coerce/to-date date) :date (coerce/to-date date)
:vendor (:db/id sysco-vendor ) :vendor (:db/id sysco-vendor)
:client (:db/id matching-client) :client (:db/id matching-client)
:import-status :import-status/imported :import-status :import-status/imported
:status :invoice-status/unpaid :status :invoice-status/unpaid
@@ -182,39 +178,30 @@
(defn get-test-invoice-file (defn get-test-invoice-file
([] (get-test-invoice-file 999)) ([] (get-test-invoice-file 999))
( [i] ([i]
(nth (->> (s3/list-objects-v2 {:bucket-name "data.prod.app.integreatconsult.com" (nth (->> (s3/list-objects-v2 {:bucket-name "data.prod.app.integreatconsult.com"
:prefix "sysco/imported"}) :prefix "sysco/imported"})
:object-summaries :object-summaries
(map :key) (map :key))
)
i))) i)))
(comment (comment
(with-bindings { #'bucket-name "data.prod.app.integreatconsult.com"} (with-bindings {#'bucket-name "data.prod.app.integreatconsult.com"}
(doall (doall
(for [n (range 930 940 ) (for [n (range 930 940)
:let [result (-> (get-test-invoice-file n) :let [result (-> (get-test-invoice-file n)
read-sysco-csv read-sysco-csv
(extract-invoice-details (get-sysco-vendor)) (extract-invoice-details (get-sysco-vendor)))]
)]
#_#_:when (not (check-okay-amount? result))] #_#_:when (not (check-okay-amount? result))]
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" (let [result (-> "sysco/error/SYSCO050_00175962_20241010122639019.csv"
read-sysco-csv read-sysco-csv
(extract-invoice-details (get-sysco-vendor)) (extract-invoice-details (get-sysco-vendor)))]
)]
result)) result)))
)
(defn import-sysco [] (defn import-sysco []
(let [sysco-vendor (get-sysco-vendor) (let [sysco-vendor (get-sysco-vendor)
@@ -223,7 +210,6 @@
:object-summaries :object-summaries
(map :key))] (map :key))]
(alog/info ::importing-sysco (alog/info ::importing-sysco
:count (count keys) :count (count keys)
:keys (pr-str keys)) :keys (pr-str keys))
@@ -256,6 +242,5 @@
(doseq [k keys] (doseq [k keys]
(mark-key k)))) (mark-key k))))
(defn -main [& _] (defn -main [& _]
(execute "sysco" import-sysco)) (execute "sysco" import-sysco))

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -40,8 +40,6 @@
:body :body
:link_token)) :link_token))
(defn exchange-public-token [public-token _] (defn exchange-public-token [public-token _]
(-> (client/post (str base-url "/item/public_token/exchange") (-> (client/post (str base-url "/item/public_token/exchange")
{:as :json {:as :json
@@ -87,9 +85,7 @@
(.getMessage (:throwable &throw-context))) (.getMessage (:throwable &throw-context)))
json)))))) json))))))
(defn get-balance [access-token]
(defn get-balance [access-token ]
(-> (client/post (str base-url "/accounts/balance/get") (-> (client/post (str base-url "/accounts/balance/get")
{:as :json {:as :json
:headers {"Content-Type" "application/json"} :headers {"Content-Type" "application/json"}
@@ -104,7 +100,6 @@
:end (str end) :end (str end)
:acct (str account-id)) :acct (str account-id))
(try+ (try+
(-> (client/post (str base-url "/transactions/get") (-> (client/post (str base-url "/transactions/get")
{:as :json {:as :json
@@ -140,6 +135,4 @@
(clojure.pprint/pprint (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")) (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) (double? v)
(str v) (str v)
:else :else
v) v)]))
]))
m)) m))
(defn export-invoices [{:keys [query-params identity]}] (defn export-invoices [{:keys [query-params identity]}]
@@ -90,7 +88,7 @@
(list (into (list) (list (into (list)
(map datomic-map->graphql-map) (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 (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/payments
[:invoice-payment/amount [:invoice-payment/amount
{:invoice-payment/payment [:payment/check-number {:invoice-payment/payment [:payment/check-number
@@ -124,13 +122,11 @@
[:invoices [[:invoice [:id :original-id]] :amount]] [:invoices [[:invoice [:id :original-id]] :amount]]
[:bank-account [:number :code :bank-name :bank-code :id]] [: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]]]] [:vendor [:name :id [:primary-contact [:name :email :phone]] [:default-account [:name :numeric-code :id]] [:address [:street1 :city :state :zip]]]]
[:client [:id :name :code]] [:client [:id :name :code]]]]]
]]] payments (graphql/query identity (venia/graphql-query {:venia/queries (->graphql query)}) {:clients [[:client/code (query-params "client-code")]]})]
payments (graphql/query identity (venia/graphql-query {:venia/queries (->graphql query)}) {:clients [ [:client/code (query-params "client-code")]]})]
{:body {:body
(list (:all-payments (:data payments)))}))) (list (:all-payments (:data payments)))})))
(defn export-sales [{:keys [query-params identity]}] (defn export-sales [{:keys [query-params identity]}]
(assert-admin identity) (assert-admin identity)
(statsd/time! [(str "export.time") {:tags #{(client-tag query-params) (statsd/time! [(str "export.time") {:tags #{(client-tag query-params)
@@ -153,7 +149,7 @@
[:line_items [:item_name :total :tax :discount :category]] [:line_items [:item_name :total :tax :discount :category]]
[:client [:id :name :code]]]]] [:client [:id :name :code]]]]]
payments (graphql/query identity (venia/graphql-query {:venia/queries (->graphql query)})) payments (graphql/query identity (venia/graphql-query {:venia/queries (->graphql query)}))
parsedouble #(some-> % Double/parseDouble) ] parsedouble #(some-> % Double/parseDouble)]
{:body {:body
(seq (map (seq (map
(fn [s] (fn [s]
@@ -206,13 +202,11 @@
(update :total #(some-> % Double/parseDouble)))) (update :total #(some-> % Double/parseDouble))))
(:all-expected-deposits (:data payments))))}))) (:all-expected-deposits (:data payments))))})))
(generate/add-encoder org.joda.time.DateTime (generate/add-encoder org.joda.time.DateTime
(fn [c jsonGenerator] (fn [c jsonGenerator]
(.writeString jsonGenerator (str c)))) (.writeString jsonGenerator (str c))))
(defn export-clients [{:keys [identity]}]
(defn export-clients[{:keys [identity]}]
(assert-admin identity) (assert-admin identity)
{:body (into [] {:body (into []
(map <-graphql) (map <-graphql)
@@ -262,11 +256,10 @@
(-> v :vendor/address :address/city) (-> v :vendor/address :address/city)
(-> v :vendor/address :address/state) (-> v :vendor/address :address/state)
(-> v :vendor/address :address/zip) (-> 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) (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"]]))] (into [["Vendor Name" "Address" "City" "State" "Zip" "Terms" "Account" "Account Code"]]))]
{:body {:body
(into [] (into []
@@ -386,7 +379,7 @@
{:id (:db/id e) {:id (:db/id e)
:date (:transaction/date e) :date (:transaction/date e)
:post_date (:transaction/post-date e) :post_date (:transaction/post-date e)
:client { :code (:client/code client) :client {:code (:client/code client)
:id (:db/id client) :id (:db/id client)
:name (:client/name client)} :name (:client/name client)}
:amount (:transaction/amount e) :amount (:transaction/amount e)
@@ -405,7 +398,6 @@
#_#_:original-id (Integer/parseInt (query-params "original")) #_#_:original-id (Integer/parseInt (query-params "original"))
:count Integer/MAX_VALUE})] :count Integer/MAX_VALUE})]
{:body (map {:body (map
(comp ->graphql (comp ->graphql
(fn [i] (fn [i]
@@ -459,10 +451,10 @@
(defn export-raw [{:keys [query-params identity]}] (defn export-raw [{:keys [query-params identity]}]
(assert-admin 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"}}] (statsd/time! [(str "export.time") {:tags #{"export:raw"}}]
{:body {: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 [_] (defn export-ntg-account-snapshot [_]
(let [clients (->> (dc/q '[:find (pull ?e [:db/id :client/code :client/locations]) (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]}] {[:charge/processor :xform iol-ion.query/ident] [:db/ident]}]
:sales-order/line-items [:order-line-item/item-name :sales-order/line-items [:order-line-item/item-name
:order-line-item/category :order-line-item/category
:order-line-item/total]} :order-line-item/total]}]
]
:start [:sales-order/client+date [(:db/id client) (coerce/to-date date)]] :start [:sales-order/client+date [(:db/id client) (coerce/to-date date)]]
:end [:sales-order/client+date [(:db/id client) (coerce/to-date end)]] :end [:sales-order/client+date [(:db/id client) (coerce/to-date end)]]
:reverse false :reverse false
@@ -576,40 +567,34 @@
(:db/id client)) (:db/id client))
(< (compare (:sales-order/date curr) (< (compare (:sales-order/date curr)
(coerce/to-date end)) (coerce/to-date end))
0)) 0)))))]
)))
]
entry all-entries entry all-entries
:let [sales-columns [(-> entry :sales-order/client :client/name) :let [sales-columns [(-> entry :sales-order/client :client/name)
(atime/unparse-local (coerce/from-date (-> entry :sales-order/date)) atime/standard-time) (atime/unparse-local (coerce/from-date (-> entry :sales-order/date)) atime/standard-time)
(-> entry :sales-order/total) (-> entry :sales-order/total)
(-> entry :sales-order/tip) (-> entry :sales-order/tip)
(-> entry :sales-order/service-charge) (-> entry :sales-order/service-charge)
(-> entry :sales-order/reference-link) (-> entry :sales-order/reference-link)]
]
sales-column-count (count sales-columns) sales-column-count (count sales-columns)
tender-column-count 6] tender-column-count 6]
row (concat [sales-columns] row (concat [sales-columns]
(map (fn [tender] (map (fn [tender]
(concat (concat
(take sales-column-count (repeat nil)) (take sales-column-count (repeat nil))
[ [(-> tender :charge/total)
(-> tender :charge/total)
(-> tender :charge/tax) (-> tender :charge/tax)
(-> tender :charge/tip) (-> tender :charge/tip)
(-> tender :charge/type-name) (-> tender :charge/type-name)
(some-> tender :charge/processor name) (some-> tender :charge/processor name)
(-> tender :charge/reference-link) (-> tender :charge/reference-link)]))
]))
(:sales-order/charges entry)) (:sales-order/charges entry))
(map (fn [tender] (map (fn [tender]
(concat (concat
(take (+ sales-column-count tender-column-count) (repeat nil)) (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/category)
(-> tender :order-line-item/total) (-> tender :order-line-item/total)]))
]))
(:sales-order/line-items entry)))] (:sales-order/line-items entry)))]
row row
@@ -617,7 +602,7 @@
_ (when balance _ (when balance
(reset! last-used-value balance)) (reset! last-used-value balance))
balance (or balance @last-used-value)] 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)])))})) (format "%.2f" balance)])))}))
#_(export-ntg-payment-snapshot nil) #_(export-ntg-payment-snapshot nil)
@@ -628,7 +613,6 @@
(handler request) (handler request)
{:status 401}))) {:status 401})))
(def routes2 {"api/" {"sales/" {"aggregated/" {#"export/?" {:get :aggregated-sales-export}} (def routes2 {"api/" {"sales/" {"aggregated/" {#"export/?" {:get :aggregated-sales-export}}
#"export/?" {:get :export-sales} #"export/?" {:get :export-sales}
"ntg-export" {:get :export-ntg-sales-snapshot}} "ntg-export" {:get :export-ntg-sales-snapshot}}
@@ -660,10 +644,9 @@
:export-ntg-sales-snapshot (-> export-ntg-sales-snapshot wrap-csv-response :export-ntg-sales-snapshot (-> export-ntg-sales-snapshot wrap-csv-response
(wrap-schema-enforce :query-schema (mc/schema [:map (wrap-schema-enforce :query-schema (mc/schema [:map
[:date {:required true [: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-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-trial-balance (-> export-trial-balance wrap-csv-response wrap-secure)
:export-accounts (-> export-accounts wrap-json-response wrap-secure) :export-accounts (-> export-accounts wrap-json-response wrap-secure)
:export-transactions (-> export-transactions wrap-json-response wrap-secure) :export-transactions (-> export-transactions wrap-json-response wrap-secure)

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -22,7 +22,7 @@
{:status 200 {:status 200
:headers {"Content-Type" "application/edn"} :headers {"Content-Type" "application/edn"}
:body (pr-str {:token token :body (pr-str {:token token
:url (:yodlee2-fastlink env)}) })) :url (:yodlee2-fastlink env)})}))
(defn refresh-provider-accounts [{:keys [identity edn-params]}] (defn refresh-provider-accounts [{:keys [identity edn-params]}]
(assert-admin identity) (assert-admin identity)
(alog/info ::refreshing :params edn-params) (alog/info ::refreshing :params edn-params)
@@ -34,7 +34,7 @@
(:provider-account-id edn-params)) (:provider-account-id edn-params))
{:status 200 {:status 200
:headers {"Content-Type" "application/edn"} :headers {"Content-Type" "application/edn"}
:body "{}" } :body "{}"}
(catch Exception e (catch Exception e
(alog/error ::error :error e) (alog/error ::error :error e)
{:status 400 {:status 400
@@ -75,7 +75,7 @@
d-clients/get-by-id d-clients/get-by-id
:client/code) :client/code)
(Long/parseLong id) (Long/parseLong id)
(dissoc data :client-id )))} (dissoc data :client-id)))}
(catch Exception e (catch Exception e
(alog/error ::error :error e) (alog/error ::error :error e)
{:status 500 {:status 500
@@ -93,7 +93,7 @@
(:provider-account-id edn-params)) (:provider-account-id edn-params))
{:status 200 {:status 200
:headers {"Content-Type" "application/edn"} :headers {"Content-Type" "application/edn"}
:body (pr-str {}) } :body (pr-str {})}
(catch Exception e (catch Exception e
(alog/error ::error :error e) (alog/error ::error :error e)
{:status 400 {:status 400
@@ -110,11 +110,11 @@
(def routes {"api" {"/yodlee2" {"/fastlink" :fastlink (def routes {"api" {"/yodlee2" {"/fastlink" :fastlink
"/provider-accounts/refresh/" :refresh-provider-accounts "/provider-accounts/refresh/" :refresh-provider-accounts
["/provider-accounts/" :client "/" :id ] :get-provider-account-detail ["/provider-accounts/" :client "/" :id] :get-provider-account-detail
["/reauthenticate/" :id ] :reauthenticate ["/reauthenticate/" :id] :reauthenticate
"/provider-accounts/delete/" :delete-provider-account}}}) "/provider-accounts/delete/" :delete-provider-account}}})
(def match->handler {:fastlink (-> fastlink wrap-secure (valid-for :get)) (def match->handler {:fastlink (-> fastlink wrap-secure (valid-for :get))
:refresh-provider-accounts (-> refresh-provider-accounts wrap-secure (valid-for :post)) :refresh-provider-accounts (-> refresh-provider-accounts wrap-secure (valid-for :post))
:get-provider-account-detail (-> get-provider-account-detail wrap-secure (valid-for :get)) :get-provider-account-detail (-> get-provider-account-detail wrap-secure (valid-for :get))
:reauthenticate (-> reauthenticate wrap-secure (valid-for :post)) :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/dom-gte :transaction-rule/dom-lte
:transaction-rule/amount-gte :transaction-rule/amount-lte :transaction-rule/amount-gte :transaction-rule/amount-lte
:transaction-rule/client :transaction-rule/bank-account :transaction-rule/client :transaction-rule/bank-account
:transaction-rule/yodlee-merchant]} ] :transaction-rule/yodlee-merchant]}]
(let [transaction-dom (some-> transaction (let [transaction-dom (some-> transaction
:transaction/date :transaction/date
.toInstant .toInstant
@@ -80,8 +80,6 @@
(recur rules))) (recur rules)))
[]))) [])))
(defn group-rules-by-priority [rules] (defn group-rules-by-priority [rules]
(->> rules (->> rules
(map (fn [r] (update r :transaction-rule/description #(some-> % ->pattern)))) (map (fn [r] (update r :transaction-rule/description #(some-> % ->pattern))))
@@ -150,7 +148,7 @@
(fn [transaction valid-locations] (fn [transaction valid-locations]
(if (:transaction/payment transaction) (if (:transaction/payment transaction)
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))] (if-let [top-match (and (= (count matching-rules) 1) (first matching-rules))]
(apply-rule transaction top-match valid-locations) (apply-rule transaction top-match valid-locations)
transaction)))))) transaction))))))

View File

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

View File

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

View File

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

View File

@@ -35,9 +35,8 @@
tx-instant))) tx-instant)))
(group-by (fn hours-ago [d] (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)] (for [h (range 24)]
(count (tx-lookup h []))))) (count (tx-lookup h [])))))
@@ -59,8 +58,7 @@
[:div [:div
[:div {:class "w-full h-64" [:div {:class "w-full h-64"
:id "client-chart" :id "client-chart"
:data-chart (hx/json { :data-chart (hx/json {:labels ["2 years ago" "1 year ago" "today"],
:labels ["2 years ago" "1 year ago" "today"],
:series [(for [n [2 1 0] :series [(for [n [2 1 0]
:let [start (time/plus (time/now) (time/years (- n)))]] :let [start (time/plus (time/now) (time/years (- n)))]]
(->> (dc/q '[:find (count ?c) (->> (dc/q '[:find (count ?c)
@@ -80,19 +78,14 @@
[:div [:div
[:div {:class "w-full h-64" [:div {:class "w-full h-64"
:id "changes" :id "changes"
:data-chart (hx/json { :data-chart (hx/json {:labels (for [n (range -24 0)]
:labels (for [n (range -24 0)]
(format "%d" n)), (format "%d" n)),
:series [(hourly-changes)]})}] :series [(hourly-changes)]})}]
[:script {:lang "javascript"} [:script {:lang "javascript"}
(hiccup/raw (hiccup/raw
"new Chartist.Line('#changes', JSON.parse(document.getElementById('changes').getAttribute('data-chart')))")]]]])] "new Chartist.Line('#changes', JSON.parse(document.getElementById('changes').getAttribute('data-chart')))")]]]])])
) "Admin"))
"Admin")
)
(def key->handler (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) (some->> query-params :type)
(merge-query {:query {:find [] (merge-query {:query {:find []
:in ['?r] :in ['?r]
:where ['[?e :account/type ?r] ]} :where ['[?e :account/type ?r]]}
:args [(some->> query-params :type)]}) :args [(some->> query-params :type)]})
true true
@@ -213,8 +213,7 @@
(map (fn [client] (map (fn [client]
(format "'%s'" (pull-attr (dc/db conn) (format "'%s'" (pull-attr (dc/db conn)
:client/name :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. :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 {:keys [tempids]} (audit-transact [[:upsert-entity (cond-> entity
@@ -278,14 +277,13 @@
(defn dialog* [{:keys [entity form-params form-errors]}] (defn dialog* [{:keys [entity form-params form-errors]}]
(fc/start-form 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)) [: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) )}) "accountCode" (or (:account/numeric-code form-params) (:account/numeric-code entity))})
:hx-target "this" :hx-target "this"}
}
(com/modal (com/modal
{} {}
[:form (-> {:hx-ext "response-targets" [:form (-> {:hx-ext "response-targets"
:hx-swap "outerHTML swap:300ms" :hx-swap "outerHTML swap:300ms"
:hx-target-400 "#form-errors .error-content" } :hx-target-400 "#form-errors .error-content"}
(assoc (if (:db/id entity) (assoc (if (:db/id entity)
:hx-put :hx-put
:hx-post) :hx-post)
@@ -381,7 +379,7 @@
(com/validated-save-button {:errors (seq form-errors)} (com/validated-save-button {:errors (seq form-errors)}
"Save account")])]])])) "Save account")])]])]))
(defn new-client-override [{ {:keys [index]} :query-params}] (defn new-client-override [{{:keys [index]} :query-params}]
(html-response (html-response
(fc/start-form-with-prefix (fc/start-form-with-prefix
[:account/client-overrides (or index 0)] [:account/client-overrides (or index 0)]
@@ -416,9 +414,6 @@
{}) {})
:form-errors form-errors}))) :form-errors form-errors})))
(def key->handler (def key->handler
(apply-middleware-to-all-handlers (apply-middleware-to-all-handlers
(->> (->>

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -14,7 +14,6 @@
:headers {"Location" "/login"} :headers {"Location" "/login"}
:session {}}) :session {}})
(defn impersonate [request] (defn impersonate [request]
{:status 200 {:status 200
:session {:identity (dissoc (jwt/unsign (get-in request [:query-params "jwt"]) :session {:identity (dissoc (jwt/unsign (get-in request [:query-params "jwt"])
@@ -39,21 +38,20 @@
next (assoc "state" (hu/url-encode next)))))))) next (assoc "state" (hu/url-encode next))))))))
(defn- page-contents [request] (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 :x-data (hx/json {:showError false
:errorDetails "" :errorDetails ""
:showNotification false :showNotification false
:notificationDetails ""}) :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#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#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 [:div.relative
[:button.absolute.right-2.top-2.w-6.h-6.z-50.text-blue-400 [:button.absolute.right-2.top-2.w-6.h-6.z-50.text-blue-400
{ "@click" "showNotification=false"} {"@click" "showNotification=false"}
svg/filled-x]] 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 [: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.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 [:div.relative
[:button.absolute.right-2.top-2.w-6.h-6.z-50.text-red-600 [:button.absolute.right-2.top-2.w-6.h-6.z-50.text-red-600
{ "@click" "showError=false"} {"@click" "showError=false"}
svg/filled-x]] 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 [: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 [:div.p-4
[:img {:src "/img/logo-big.png"}] [: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"]] [:a.button.is-large.is-primary {:href (login-url (get (:query-params request) "redirect-to"))} "Login with Google"]]
"HELLO"]) "HELLO"])]]]])
]]] ])
(defn login [request] (defn login [request]
(base-page (base-page

View File

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

View File

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

View File

@@ -24,7 +24,7 @@
(def query-schema (mc/schema (def query-schema (mc/schema
[:maybe [:maybe
(into [:map {} ] (into [:map {}]
default-grid-fields-schema)])) default-grid-fields-schema)]))
(def vendor-read '[:db/id (def vendor-read '[:db/id
@@ -49,7 +49,7 @@
:in $ ?c ?v :in $ ?c ?v
:where :where
[?p :payment/client ?c] [?p :payment/client ?c]
[?p :payment/date ?d ] [?p :payment/date ?d]
[(>= ?d #inst "2025-01-01T08:00")] [(>= ?d #inst "2025-01-01T08:00")]
[(< ?d #inst "2026-01-01T08:00")] [(< ?d #inst "2026-01-01T08:00")]
[?p :payment/type :payment-type/check] [?p :payment/type :payment-type/check]
@@ -68,7 +68,7 @@
:in $ [?c ...] vendor-read :in $ [?c ...] vendor-read
:where :where
[?p :payment/client ?c] [?p :payment/client ?c]
[?p :payment/date ?d ] [?p :payment/date ?d]
[(>= ?d #inst "2025-01-01T08:00")] [(>= ?d #inst "2025-01-01T08:00")]
[(< ?d #inst "2026-01-01T08:00")] [(< ?d #inst "2026-01-01T08:00")]
[?p :payment/type :payment-type/check] [?p :payment/type :payment-type/check]
@@ -81,7 +81,7 @@
(filter (fn [[_ _ a]] (filter (fn [[_ _ a]]
(>= (or a 0.0) 600.0))) (>= (or a 0.0) 600.0)))
(sort-by (fn [[client _ amount]] (sort-by (fn [[client _ amount]]
[(:client/code client ) amount])) [(:client/code client) amount]))
(into [])) (into []))
paginated (apply-pagination-raw {:start (:start query-params) paginated (apply-pagination-raw {:start (:start query-params)
:per-page (:per-page query-params)} all)] :per-page (:per-page query-params)} all)]
@@ -129,8 +129,7 @@
(com/pill (com/pill
{:class "text-xs font-medium" {:class "text-xs font-medium"
:color :primary} :color :primary}
(str/capitalize t99-type)) (str/capitalize t99-type)))])}
)])}
{:key "tin" {:key "tin"
:name "TIN" :name "TIN"
:sort-key "tin" :sort-key "tin"
@@ -143,8 +142,7 @@
(when-let [tin-type (some-> vendor :vendor/legal-entity-tin-type :db/ident name)] (when-let [tin-type (some-> vendor :vendor/legal-entity-tin-type :db/ident name)]
(com/pill {:class "text-xs font-medium" (com/pill {:class "text-xs font-medium"
:color :yellow} :color :yellow}
(name tin-type)))] (name tin-type)))])}
)}
{:key "expense-account" {:key "expense-account"
:name "Expense Account" :name "Expense Account"
:show-starting "md" :show-starting "md"
@@ -152,7 +150,7 @@
[:div.flex.gap-4 [:div.flex.gap-4
(when-let [tin (-> vendor :vendor/default-account :account/name)] (when-let [tin (-> vendor :vendor/default-account :account/name)]
[:span {:class "text-xs font-medium py-0.5 "} [:span {:class "text-xs font-medium py-0.5 "}
tin]) ])} tin])])}
{:key "address" {:key "address"
:name "Address" :name "Address"
:sort-key "address" :sort-key "address"
@@ -176,8 +174,6 @@
:color :primary} :color :primary}
"Paid $" (Math/round paid)))}]})) "Paid $" (Math/round paid)))}]}))
(def table* (partial helper/table* grid-page)) (def table* (partial helper/table* grid-page))
(def row* (partial helper/row* grid-page)) (def row* (partial helper/row* grid-page))
@@ -185,7 +181,6 @@
{:keys [vendor-id]} :route-params {:keys [vendor-id]} :route-params
{:keys [client-id]} :query-params}] {:keys [client-id]} :query-params}]
(assert-can-see-client identity client-id) (assert-can-see-client identity client-id)
@(dc/transact conn [[:upsert-entity (-> form-params @(dc/transact conn [[:upsert-entity (-> form-params
@@ -198,20 +193,18 @@
(:address/zip a) (:address/zip a)
(:db/id a)) (:db/id a))
a a
nil)) ))]]) nil))))]])
(html-response (html-response
(row* identity [(dc/pull (dc/db conn) [:db/id :client/code] client-id) (row* identity [(dc/pull (dc/db conn) [:db/id :client/code] client-id)
(dc/pull (dc/db conn) vendor-read vendor-id) (dc/pull (dc/db conn) vendor-read vendor-id)
(sum-for-client-vendor client-id vendor-id) (sum-for-client-vendor client-id vendor-id)] {:flash? true})
] {:flash? true})
:headers {"hx-trigger" "modalclose" :headers {"hx-trigger" "modalclose"
"hx-retarget" (format "#entity-table tr[data-id=\"%d\"]" vendor-id)})) "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] (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]}]) [:vendor/legal-entity-tin-type :xform iol-ion.query/ident] [:db/ident]}])
(def form-schema (mc/schema [:map (def form-schema (mc/schema [:map
[:vendor/address {:default {}} [:vendor/address {:default {}}
[:maybe [:maybe
@@ -221,7 +214,7 @@
[:address/street2 {:optional true} [:maybe [:string {:decode/string strip}]]] [:address/street2 {:optional true} [:maybe [:string {:decode/string strip}]]]
[:address/city {: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/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}|)$"]]]]]] :decode/string strip} #"^(\d{5}|)$"]]]]]]
[:vendor/legal-entity-name {:optional true} [:maybe [:string {:decode/string strip}]]] [:vendor/legal-entity-name {:optional true} [:maybe [:string {:decode/string strip}]]]
[:vendor/legal-entity-first-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])) [malli.core :as mc]))
(def query-schema (mc/schema (def query-schema (mc/schema
[:maybe [:maybe
(into [:map {} ] (into [:map {}]
default-grid-fields-schema)])) default-grid-fields-schema)]))
(def default-read '[:db/id (def default-read '[:db/id
@@ -37,7 +37,7 @@
{:plaid-item/accounts [:db/id {:plaid-item/accounts [:db/id
{:bank-account/_plaid-account [{:bank-account/integration-status {: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/message
:integration-status/last-attempt :integration-status/last-attempt
:integration-status/last-updated]}]} :integration-status/last-updated]}]}
@@ -66,7 +66,6 @@
true (apply-sort-3 query-params) true (apply-sort-3 query-params)
true (apply-pagination query-params)))) true (apply-pagination query-params))))
(defn hydrate-results [ids db _] (defn hydrate-results [ids db _]
(let [results (pull-many-by-id db default-read ids)] (let [results (pull-many-by-id db default-read ids)]
(->> ids (->> ids
@@ -78,15 +77,12 @@
[(hydrate-results ids-to-retrieve db request) [(hydrate-results ids-to-retrieve db request)
matching-count])) matching-count]))
(defn plaid-link-script [token] (defn plaid-link-script [token]
(format "window.plaid = Plaid.create( (format "window.plaid = Plaid.create(
{ token: \"%s\", { token: \"%s\",
onSuccess: function (x) { htmx.trigger(\"#link-account\", \"linked\", {\"public_token\": x})} onSuccess: function (x) { htmx.trigger(\"#link-account\", \"linked\", {\"public_token\": x})}
})", token)) })", token))
(defn link [{{client-code "client_code" public-token "public_token"} :form-params (defn link [{{client-code "client_code" public-token "public_token"} :form-params
:keys [identity] :keys [identity]
:as request}] :as request}]
@@ -99,9 +95,9 @@
(alog/info ::linking-plaid :id identity :client-code client-code) (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])) (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)) (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] 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/access-token access-token
:plaid-item/status (or (some-> account-result :item :error) :plaid-item/status (or (some-> account-result :item :error)
"SUCCESS") "SUCCESS")
@@ -141,7 +137,6 @@
(com/button-icon {} svg/refresh) (com/button-icon {} svg/refresh)
"Start relink")]))) "Start relink")])))
(def grid-page (def grid-page
(helper/build (helper/build
{:id "plaid-table" {:id "plaid-table"
@@ -211,7 +206,6 @@
(when bad-integration (when bad-integration
" (detail)") " (detail)")
(when bad-integration (when bad-integration
[:template {:x-ref "tooltip"} [:template {:x-ref "tooltip"}
[:div.text-red-700 [: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 " [: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)])])}]})) (atime/unparse-local (:plaid-account/last-synced a) atime/normal-date)])])}]}))
(def page (helper/page-route grid-page)) (def page (helper/page-route grid-page))
(def table (helper/table-route grid-page)) (def table (helper/table-route grid-page))
(def key->handler (def key->handler
(apply-middleware-to-all-handlers (apply-middleware-to-all-handlers
{ {:company-plaid page
:company-plaid page
:company-plaid-table table :company-plaid-table table
:company-plaid-link link :company-plaid-link link
:company-plaid-relink relink :company-plaid-relink relink}
}
(fn [h] (fn [h]
(-> h (-> h
(wrap-copy-qp-pqp) (wrap-copy-qp-pqp)

View File

@@ -32,8 +32,7 @@
[:maybe clj-date-schema]] [:maybe clj-date-schema]]
[:end-date {:optional true} [:end-date {:optional true}
[:maybe clj-date-schema]] [: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)])) 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]) (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]]} :where '[[?e :report/client ?c]]}
:args [db (:trimmed-clients request)]} :args [db (:trimmed-clients request)]}
(:sort query-params) (add-sorter-fields {"client" ['[?e :report/client ?c] (:sort query-params) (add-sorter-fields {"client" ['[?e :report/client ?c]
'[?c :client/name ?sort-client]] '[?c :client/name ?sort-client]]
"created" ['[?e :report/created ?sort-created]] "created" ['[?e :report/created ?sort-created]]
"creator" ['[?e :report/creator ?sort-creator]] "creator" ['[?e :report/creator ?sort-creator]]
"name" ['[?e :report/name ?sort-name] "name" ['[?e :report/name ?sort-name]]}
]}
query-params) query-params)
true true
@@ -115,7 +112,7 @@
:sort-key "creator" :sort-key "creator"
:render (fn [report] :render (fn [report]
(when (:report/creator report) (when (:report/creator report)
(com/pill {:color :primary } (com/pill {:color :primary}
(:report/creator report))))} (:report/creator report))))}
{:key "created" {:key "created"
:name "Created" :name "Created"
@@ -147,7 +144,6 @@
{:flash? true {:flash? true
:delete-after-settle? true})))) :delete-after-settle? true}))))
(def key->handler (def key->handler
(apply-middleware-to-all-handlers (apply-middleware-to-all-handlers
(->> (->>
@@ -159,7 +155,7 @@
(into company-reconciliation-report/key->handler)) (into company-reconciliation-report/key->handler))
(fn [h] (fn [h]
(-> h (-> h
(wrap-copy-qp-pqp) (wrap-copy-qp-pqp)
(wrap-apply-sort grid-page) (wrap-apply-sort grid-page)
(wrap-merge-prior-hx) (wrap-merge-prior-hx)
(wrap-schema-enforce :query-schema query-schema) (wrap-schema-enforce :query-schema query-schema)

View File

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

View File

@@ -53,7 +53,7 @@
(com/data-grid-cell {:class class} (com/data-grid-cell {:class class}
(when (> (count (:missing-transactions row)) 0) (when (> (count (:missing-transactions row)) 0)
[:div [: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 [:div.flex.gap-2.items-center
(count (:missing-transactions row)) (count (:missing-transactions row))
[:div.w-4.h-4 svg/question]]) [:div.w-4.h-4 svg/question]])
@@ -67,7 +67,6 @@
(com/data-grid-cell {} (com/data-grid-cell {}
(format "$%,.2f" (:transaction/amount r))))))]]))))))]) (format "$%,.2f" (:transaction/amount r))))))]]))))))])
(defn reconciliation-card* [{:keys [request report]}] (defn reconciliation-card* [{:keys [request report]}]
(com/content-card {:class "w-full" :id "reconciliation-report"} (com/content-card {:class "w-full" :id "reconciliation-report"}
[:div {:class "flex flex-col px-8 py-8 space-y-3"} [:div {:class "flex flex-col px-8 py-8 space-y-3"}
@@ -88,7 +87,7 @@
(com/date-input {:name (fc/field-name) (com/date-input {:name (fc/field-name)
:class "w-64" :class "w-64"
:value (some-> (fc/field-value) :value (some-> (fc/field-value)
(atime/unparse-local atime/normal-date)) })])) (atime/unparse-local atime/normal-date))})]))
(fc/with-field :end-date (fc/with-field :end-date
(com/validated-field {:label "End" (com/validated-field {:label "End"
:errors (fc/field-errors)} :errors (fc/field-errors)}
@@ -96,12 +95,11 @@
(com/date-input {:name (fc/field-name) (com/date-input {:name (fc/field-name)
:class "w-64" :class "w-64"
:value (some-> (fc/field-value) :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")])] (com/button {:color :primary :class "self-center w-24"} "Run")])]
(if report (if report
(report* {:request request :report 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] (defn page [request]
(base-page (base-page
@@ -134,7 +132,7 @@
url/map->query)) url/map->query))
(defn get-report-data [start-date end-date client-ids] (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)) (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) :let [raw-transactions (get-transactions (atime/unparse-local start-date atime/iso-date)
(atime/unparse-local end-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) :requires-feedback-count (:transaction-approval-status/requires-feedback found-transactions 0)
:missing-transactions missing-transactions}))) :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) (let [client-ids (extract-client-ids (:clients request)
(:client-id request) (:client-id request)
(when (:client-code request) (when (:client-code request)
@@ -191,4 +189,4 @@
[:start-date {:optional true} [:start-date {:optional true}
[:maybe clj-date-schema]] [:maybe clj-date-schema]]
[:end-date {:optional true} [:end-date {:optional true}
[:maybe clj-date-schema]] ]))))) [:maybe clj-date-schema]]])))))

View File

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

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