enormous refactor but simplified much!

This commit is contained in:
Bryce Covert
2021-12-22 18:14:49 -08:00
parent a7c9d376bc
commit 7489426ccb
25 changed files with 1188 additions and 1258 deletions

View File

@@ -1,6 +1,5 @@
(ns auto-ap.routes.events
(:require [auto-ap.routes.utils :refer [wrap-secure]]
[auto-ap.yodlee.import :as yodlee-import]
[config.core :refer [env]]
[clj-http.client :as http]
[clj-time.coerce :as c]

View File

@@ -5,13 +5,14 @@
[auto-ap.datomic.invoices :as d-invoices]
[auto-ap.datomic.vendors :as d-vendors]
[auto-ap.graphql.utils :refer [assert-admin assert-can-see-client]]
[auto-ap.import.manual :as manual]
[auto-ap.import.manual.common :as c]
[auto-ap.logging :refer [info-event]]
[auto-ap.parse :as parse]
[auto-ap.parse.util :as parse-u]
[auto-ap.routes.utils :refer [wrap-secure]]
[auto-ap.time-utils :refer [next-dom]]
[auto-ap.utils :refer [by]]
[auto-ap.yodlee.import :refer [grouped-import] :as y]
[clj-time.coerce :as coerce :refer [to-date]]
[clj-time.core :as time]
[clojure.data.csv :as csv]
@@ -73,50 +74,6 @@
(get (by (comp :db/id :vendor-schedule-payment-dom/client) :vendor-schedule-payment-dom/dom (:vendor/schedule-payment-dom vendor))
client-id))
(defn parse-amount [i]
(try
(Double/parseDouble (str/replace (or (second
(re-matches #"[^0-9\.,\\-]*([0-9\.,\\-]+)[^0-9\.,]*" (:amount i)))
"0")
#"," ""))
(catch Exception e
(throw (Exception. (str "Could not parse total from value '" (:amount i) "'") e)))))
(defn parse-account-numeric-code [i]
(try
(when-let [account-numeric-code (:account-numeric-code i)]
(:db/id (d-accounts/get-account-by-numeric-code-and-sets (Integer/parseInt account-numeric-code)
["default"])))
(catch Exception e
(throw (Exception. (str "Could not parse expense account from value '" (:account-numeric-code i) "'") e)))))
(defn parse-account-id [i]
(try
(Long/parseLong (second
(re-matches #"[^0-9,\\-]*([0-9,\\-]+)[^0-9,]*" (:bank-account-id i))))
(catch Exception e
(throw (Exception. (str "Could not parse account from value '" (:bank-account-id i) "'") e)))))
(defn parse-date [{:keys [raw-date]}]
(when-not
(re-find #"\d{1,2}/\d{1,2}/\d{4}" raw-date)
(throw (Exception. (str "Date " raw-date " must match MM/dd/yyyy"))))
(try
(parse-u/parse-value :clj-time "MM/dd/yyyy" raw-date)
(catch Exception e
(throw (Exception. (str "Could not parse date from '" raw-date "'") e)))))
(defn parse-or-error [key f]
(fn [x]
(try
(assoc x key (f x))
(catch Exception e
(update x :errors conj {:info (.getMessage e)
:details (str e)})))))
(defn parse-invoice-rows [excel-rows]
(let [columns [:raw-date :vendor-name :check :location :invoice-number :amount :client-name :bill-entered :bill-rejected :added-on :exported-on :account-numeric-code]
all-vendors (by :vendor/name (d-vendors/get-graphql {}))
@@ -127,15 +84,15 @@
(map #(into {} (map (fn [c k] [k c] ) % columns)))
(map reset-id)
(map assoc-client-code)
(map (parse-or-error :client-id #(parse-client % all-clients)))
(map (parse-or-error :vendor #(parse-vendor % all-vendors)))
(map (parse-or-error :vendor-id #(parse-vendor-id %)))
(map (parse-or-error :automatically-paid-when-due #(parse-automatically-paid-when-due %)))
(map (parse-or-error :schedule-payment-dom #(parse-schedule-payment-dom %)))
(map (parse-or-error :account-id parse-account-numeric-code))
(map (parse-or-error :invoice-number parse-invoice-number))
(map (parse-or-error :total parse-amount))
(map (parse-or-error :date parse-date)))]
(map (c/parse-or-error :client-id #(parse-client % all-clients)))
(map (c/parse-or-error :vendor #(parse-vendor % all-vendors)))
(map (c/parse-or-error :vendor-id #(parse-vendor-id %)))
(map (c/parse-or-error :automatically-paid-when-due #(parse-automatically-paid-when-due %)))
(map (c/parse-or-error :schedule-payment-dom #(parse-schedule-payment-dom %)))
(map (c/parse-or-error :account-id c/parse-account-numeric-code))
(map (c/parse-or-error :invoice-number parse-invoice-number))
(map (c/parse-or-error :total c/parse-amount))
(map (c/parse-or-error :date c/parse-date)))]
rows))
@@ -428,6 +385,9 @@
rows)]
@(d/transact (d/connect uri) txes)))
(defroutes routes
(wrap-routes
(context "/" []
@@ -435,55 +395,18 @@
(POST "/batch-upload"
{{:keys [data]} :edn-params user :identity}
(assert-admin user)
(try
#_(throw (Exception. "Unexpected error"))
(let [columns [:status :raw-date :description-original :high-level-category nil nil :amount nil nil nil nil nil :bank-account-code :client-code]
all-clients (d-clients/get-all)
all-bank-accounts (mapcat :client/bank-accounts all-clients)
all-clients (merge (by :client/code all-clients) (by :client/name all-clients))
all-bank-accounts (merge (by :bank-account/code all-bank-accounts))
rows (->> (str/split data #"\n" )
(drop 1)
(map #(str/split % #"\t"))
(map #(into {} (filter identity (map (fn [c k] [k c] ) % columns))))
(map (parse-or-error :amount parse-amount))
(map (parse-or-error :date parse-date))
(map (fn [{:keys [bank-account-code] :as row}]
(if-let [bank-account-id (:db/id (all-bank-accounts bank-account-code))]
(assoc row :bank-account-id bank-account-id)
(update row :errors conj {:info (str "Cannot find bank by code " bank-account-code)
:details (str "Cannot find bank by code " bank-account-code)}))))
(map (fn [{:keys [client-code] :as row}]
(if-let [client-id (:db/id (all-clients client-code))]
(assoc row :client-id client-id)
(update row :errors conj {:info (str "Cannot find client by code " client-code)
:details (str "Cannot find client by code " client-code)})))))
error-rows (filter :errors rows)
_ (log/info "Importing " (count rows) "raw transactions")
raw-transactions (vec (->> rows
(filter #(not (seq (:errors %))) )
(map (fn [row]
(select-keys row [:description-original :client-code :status :high-level-category :amount :bank-account-id :date :client-id])))))
import-id (y/start-import :import-source/manual (:user/name user))
result (grouped-import raw-transactions import-id)]
(y/finish-import {:db/id import-id
:import-batch/imported (count (:import result))
:import-batch/suppressed (count (:suppressed result))
:import-batch/extant (count (:extant result))})
{:status 200
:body (pr-str {:imported (count (:import result))
:errors (map #(dissoc % :date) error-rows)})
:headers {"Content-Type" "application/edn"}})
(let [stats (manual/import-batch (manual/tabulate-data data) (:user/name user))]
{:status 200
:body (pr-str stats)
:headers {"Content-Type" "application/edn"}})
(catch Exception e
(log/error e)
{:status 500
:body (pr-str {:message (.getMessage e)
:error (.toString e)
:data (ex-data e)})
:headers {"Content-Type" "application/edn"}}))
))
:headers {"Content-Type" "application/edn"}}))))
(context "/invoices" []
(POST "/upload"