From aa6ed8355b7ffd02cedbeadc91c81b33af2dc6ce Mon Sep 17 00:00:00 2001 From: Bryce Covert Date: Thu, 14 May 2020 07:00:59 -0700 Subject: [PATCH] several fixes. --- src/clj/auto_ap/datomic/migrate.clj | 5 +- .../datomic/migrate/add_general_ledger.clj | 4 +- src/clj/auto_ap/ledger.clj | 1 + src/clj/auto_ap/routes/invoices.clj | 48 +++++++++++++++---- src/clj/auto_ap/yodlee/import.clj | 4 +- src/clj/user.clj | 28 +++++++++++ src/cljs/auto_ap/subs.cljs | 6 +++ .../views/components/invoice_table.cljs | 15 +++++- .../auto_ap/views/pages/ledger/table.cljs | 4 +- 9 files changed, 100 insertions(+), 15 deletions(-) diff --git a/src/clj/auto_ap/datomic/migrate.clj b/src/clj/auto_ap/datomic/migrate.clj index 85e325d0..b4c1a9da 100644 --- a/src/clj/auto_ap/datomic/migrate.clj +++ b/src/clj/auto_ap/datomic/migrate.clj @@ -228,7 +228,10 @@ :db/doc "client override" :db/valueType :db.type/string :db/cardinality :db.cardinality/one}]]} - }] + :auto-ap/add-cleared-against {:txes [[{:db/ident :transaction/cleared-against + :db/doc "which entitiy it was cleared against" + :db/valueType :db.type/string + :db/cardinality :db.cardinality/one}]]}}] (println "Conforming database...") (c/ensure-conforms conn norms-map) (when (not (seq args)) diff --git a/src/clj/auto_ap/datomic/migrate/add_general_ledger.clj b/src/clj/auto_ap/datomic/migrate/add_general_ledger.clj index 12a9367f..1a090c82 100644 --- a/src/clj/auto_ap/datomic/migrate/add_general_ledger.clj +++ b/src/clj/auto_ap/datomic/migrate/add_general_ledger.clj @@ -15,7 +15,9 @@ @(d/transact (d/connect auto-ap.datomic/uri) tx) (when (= 0 (mod i 100)) - (println "processed " i)))) + (println "processed " i) + (println "sample: " (first tx)) + ))) diff --git a/src/clj/auto_ap/ledger.clj b/src/clj/auto_ap/ledger.clj index 7569282b..69c95e25 100644 --- a/src/clj/auto_ap/ledger.clj +++ b/src/clj/auto_ap/ledger.clj @@ -75,6 +75,7 @@ :journal-entry/original-entity (:db/id entity) :journal-entry/vendor (:db/id (:transaction/vendor entity)) :journal-entry/amount (Math/abs (:transaction/amount entity)) + :journal-entry/cleared-against (:transaction/cleared-against entity) :journal-entry/line-items (into [(remove-nils {:journal-entry-line/account (:db/id (:transaction/bank-account entity)) :journal-entry-line/location "A" diff --git a/src/clj/auto_ap/routes/invoices.clj b/src/clj/auto_ap/routes/invoices.clj index 734e49fe..c89c5487 100644 --- a/src/clj/auto_ap/routes/invoices.clj +++ b/src/clj/auto_ap/routes/invoices.clj @@ -17,7 +17,9 @@ [ring.middleware.json :refer [wrap-json-response]] [compojure.core :refer [GET POST context defroutes wrap-routes]] - [clojure.string :as str])) + [clojure.string :as str] + [clojure.java.io :as io] + [clojure.data.csv :as csv])) (defn reset-id [i] (update i :invoice-number @@ -273,6 +275,20 @@ +(defn import-transactions-cleared-against [file] + (let [[header & rows] (-> file (io/reader) csv/read-csv) + txes (transduce + (comp + (filter (fn [[transaction-id cleared-against]] + (d/pull (d/db (d/connect uri)) '[:transaction/amount] (Long/parseLong transaction-id)))) + (map (fn [[transaction-id cleared-against]] + {:db/id (Long/parseLong transaction-id) + :transaction/cleared-against cleared-against}))) + conj + [] + rows)] + @(d/transact (d/connect uri) txes))) + (defroutes routes (wrap-routes (context "/" [] @@ -346,8 +362,8 @@ :body (pr-str {:message (.getMessage e) :error (.toString e) :data (ex-data e)}) - :headers {"Content-Type" "application/edn"}})) - )) + :headers {"Content-Type" "application/edn"}})))) + (POST "/upload-integreat" {{:keys [excel-rows]} :edn-params user :identity} (assert-admin user) @@ -369,20 +385,36 @@ :else :new)) parsed-invoice-rows) - - vendors-not-found (->> parsed-invoice-rows (filter #(and (nil? (:vendor-id %)) (not= "Cash" (:check %)))) (map :vendor-name) set) - inserted-rows @(d/transact (d/connect uri) (invoice-rows->transaction (:new grouped-rows)))] - {:status 200 :body (pr-str {:imported (count (:new grouped-rows)) :already-imported (count (:exists grouped-rows)) :vendors-not-found vendors-not-found :errors (map #(dissoc % :date) (:error grouped-rows))}) - :headers {"Content-Type" "application/edn"}})))) + :headers {"Content-Type" "application/edn"}}))) + (POST "/transactions/cleared-against" + {{files :file + files-2 "file"} :params :as params + user :identity} + (let [files (or files files-2) + _ (println files) + {:keys [filename tempfile]} files] + (assert-admin user) + (try + (import-transactions-cleared-against (.getPath tempfile)) + {:status 200 + :body (pr-str {}) + :headers {"Content-Type" "application/edn"}} + (catch Exception e + (println e) + {:status 500 + :body (pr-str {:message (.getMessage e) + :error (.toString e) + :data (ex-data e)}) + :headers {"Content-Type" "application/edn"}}))))) wrap-secure)) diff --git a/src/clj/auto_ap/yodlee/import.clj b/src/clj/auto_ap/yodlee/import.clj index 5bc045bc..0f62c4a7 100644 --- a/src/clj/auto_ap/yodlee/import.clj +++ b/src/clj/auto_ap/yodlee/import.clj @@ -165,8 +165,8 @@ (range) transaction-group)))) all-rules (tr/get-all) - all-bank-accounts (get-all-bank-accounts) - transaction->bank-account (comp (by :db/id all-bank-accounts) :bank-account-id)] + all-bank-accounts (by :db/id (get-all-bank-accounts)) + transaction->bank-account (comp all-bank-accounts :bank-account-id)] (println "importing manual transactions" transformed-transactions) (batch-transact (transactions->txs transformed-transactions transaction->bank-account (rm/rule-applying-fn all-rules) (get-existing))))) diff --git a/src/clj/user.clj b/src/clj/user.clj index 3a4db57b..4eb5f0ed 100644 --- a/src/clj/user.clj +++ b/src/clj/user.clj @@ -225,3 +225,31 @@ [] rows)] @(d/transact conn txes))) + +(defn cash-flow-simple [] + (->> (d/query {:query {:find '[?account-type-ident ?date ?debit ?credit] + :in '[$ ?client] + :where ['[?j :journal-entry/line-items ?je] + '[?j :journal-entry/date ?date] + '[?je :journal-entry-line/account ?a] + '[(get-else $ ?je :journal-entry-line/debit 0.0) ?debit] + '[(get-else $ ?je :journal-entry-line/credit 0.0) ?credit] + '[?a :account/type ?account-type] + '[?account-type :db/ident ?account-type-ident]]} + :args [(d/db (d/connect uri)) "CBC"]}) + + (reduce + (fn [result [account-type date debit credit]] + (let [date (clj-time.coerce/from-date date)] + (let [year-month (str (clj-time.core/year date) "-" (clj-time.core/month date))] + (-> result + (update-in [year-month account-type :debit] + (fn [existing-debit] + (+ (or existing-debit 0.0) + debit))) + (update-in [year-month account-type :credit] + (fn [existing-credit] + (+ (or existing-credit 0.0) + credit))) + (update-in [year-month account-type :count] #(inc (or % 0))))))) + {}))) diff --git a/src/cljs/auto_ap/subs.cljs b/src/cljs/auto_ap/subs.cljs index dbfe89dc..b940b7f3 100644 --- a/src/cljs/auto_ap/subs.cljs +++ b/src/cljs/auto_ap/subs.cljs @@ -94,6 +94,12 @@ [] clients)))) +(re-frame/reg-sub + ::bank-accounts-by-id + :<- [::bank-accounts] + (fn [as] + (by :id as))) + ;; Bank accounts only, not including cash (re-frame/reg-sub ::real-bank-accounts diff --git a/src/cljs/auto_ap/views/components/invoice_table.cljs b/src/cljs/auto_ap/views/components/invoice_table.cljs index ade72f92..70a6dedf 100644 --- a/src/cljs/auto_ap/views/components/invoice_table.cljs +++ b/src/cljs/auto_ap/views/components/invoice_table.cljs @@ -10,6 +10,7 @@ [reagent.core :as reagent] [clojure.string :as str] [cljs-time.format :as format] + [cljs-time.core :as t] [goog.string :as gstring] [goog.i18n.NumberFormat.Format]) ) @@ -86,8 +87,18 @@ (:name client))]) [:td (:name vendor)] [:td invoice-number] - [:td (date->str date) ] - [:td (date->str due) ] + [:td (date->str date) ] + [:td + (when due + (let [today (t/at-midnight (t/now)) + due (t/at-midnight due) + due-in (if (t/after? today due) + (- (t/in-days (t/interval (t/minus due (t/days 1)) today))) + (t/in-days (t/interval today due )))] + (if (> due-in 0) + [:span.has-text-success due-in " days"] + [:span.has-text-danger due-in " days"]) + ))] [:td (str/join ", " (set (map :location expense-accounts)))] [:td.has-text-right (nf total )] diff --git a/src/cljs/auto_ap/views/pages/ledger/table.cljs b/src/cljs/auto_ap/views/pages/ledger/table.cljs index ba9f9124..8a3ab2e9 100644 --- a/src/cljs/auto_ap/views/pages/ledger/table.cljs +++ b/src/cljs/auto_ap/views/pages/ledger/table.cljs @@ -25,6 +25,7 @@ {:keys [journal-entries start end count total]} @ledger-page selected-client @(re-frame/subscribe [::subs/client]) accounts-by-id @(re-frame/subscribe [::subs/accounts-by-id selected-client]) + bank-accounts-by-id @(re-frame/subscribe [::subs/bank-accounts-by-id]) percentage-size (if selected-client "25%" "33%") opc (fn [e] (re-frame/dispatch [::params-changed e]))] @@ -115,7 +116,8 @@ (when status? [:td status])]] (for [{:keys [debit credit location account id]} line-items - :let [account (accounts-by-id (:id account))]] + :let [account (or (accounts-by-id (:id account)) + (bank-accounts-by-id (:id account)))]] ^{:key id} [:tr {:class (:class i)} (when-not selected-client