(ns auto-ap.import.manual (:require [auto-ap.datomic :refer [conn]] [auto-ap.import.manual.common :as c] [auto-ap.import.transactions :as t] [clj-time.coerce :as coerce] [clojure.data.csv :as csv] [datomic.client.api :as dc] [unilog.context :as lc])) (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] (->> (csv/read-csv data :separator \tab) (drop 1) (map (fn [row] (into {} (->> (map vector columns row) (filter (fn [[k _]] k)))))))) (defn manual->transaction [{:keys [description-original bank-account-code] :as transaction} bank-account-lookup client-lookup] (-> {:transaction/description-original description-original :transaction/status "POSTED"} (c/assoc-or-error :transaction/client #(if-let [client-id (client-lookup bank-account-code)] client-id (throw (Exception. (str "Cannot find client for bank account code " bank-account-code))))) (c/assoc-or-error :transaction/bank-account #(if-let [bank-account-id (bank-account-lookup bank-account-code)] bank-account-id (throw (Exception. (str "Cannot find bank account by code " bank-account-code))))) (c/assoc-or-error :transaction/date #(coerce/to-date (c/parse-date transaction))) (c/assoc-or-error :transaction/amount #(c/parse-amount transaction)))) (defn import-batch [transactions user] (lc/with-context {:source "Manual import transactions"} (let [bank-account-code->client (into {} (dc/q '[:find ?bac ?c :in $ :where [?c :client/bank-accounts ?ba] [?ba :bank-account/code ?bac]] (dc/db conn))) bank-account-code->bank-account (into {} (dc/q '[:find ?bac ?ba :in $ :where [?ba :bank-account/code ?bac]] (dc/db conn))) import-batch (t/start-import-batch :import-source/manual user) transactions (->> transactions (map (fn [t] (manual->transaction t bank-account-code->bank-account bank-account-code->client))) (t/apply-synthetic-ids ))] (try (doseq [transaction transactions] (when-not (seq (:errors transaction)) (t/import-transaction! import-batch transaction))) (t/finish! import-batch) (assoc (t/get-stats import-batch) :failed-validation (count (filter :errors transactions)) :sample-error (first (first (map :errors (filter :errors transactions))))) (catch Exception e (t/fail! import-batch e) (t/get-stats import-batch))))))