so many bug fixes.
This commit is contained in:
@@ -48,7 +48,7 @@
|
||||
(let [jwt (jwt/sign (doto {:user (:name profile)
|
||||
:exp (time/plus (time/now) (time/days 30))
|
||||
:user/clients (map (fn [c]
|
||||
(dissoc c :client/bank-accounts :client/location-matches))
|
||||
(dissoc c :client/bank-accounts :client/location-matches :client/forecasted-transactions :client/matches :client/weekly-debits :client/weekly-credits :client/signature-file :client/address))
|
||||
(:user/clients user))
|
||||
:user/role (name (:user/role user))
|
||||
:user/name (:name profile)}
|
||||
|
||||
@@ -93,7 +93,11 @@
|
||||
|
||||
|
||||
(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)))))
|
||||
@@ -197,10 +201,12 @@
|
||||
|
||||
(defn import-uploaded-invoice [client forced-location forced-vendor imports]
|
||||
(let [clients (d-clients/get-all)
|
||||
transactions (reduce (fn [result {:keys [invoice-number customer-identifier total date vendor-code text full-text] :as info}]
|
||||
transactions (reduce (fn [result {:keys [invoice-number customer-identifier account-number total date vendor-code text full-text] :as info}]
|
||||
(println "searching for" vendor-code)
|
||||
(let [ _ (println "matching" customer-identifier)
|
||||
matching-client (or (and customer-identifier
|
||||
matching-client (or (and account-number
|
||||
(parse/best-match clients account-number 0.0))
|
||||
(and customer-identifier
|
||||
(parse/best-match clients customer-identifier))
|
||||
(if client
|
||||
(first (filter (fn [c]
|
||||
@@ -274,8 +280,113 @@
|
||||
(throw (ex-info "No invoices found."
|
||||
{:imports (str imports)})))
|
||||
@(d/transact (d/connect uri) (vec (set transactions)))))
|
||||
|
||||
|
||||
(defn validate-account-rows [rows code->existing-account]
|
||||
(when-let [bad-types (seq (->> rows
|
||||
(filter (fn [[account _ _ type :as row]]
|
||||
(and (not (code->existing-account (Integer/parseInt account)))
|
||||
(not (#{"Asset" "Liability" "Revenue" "Expense" "Equity" "Dividend"} type)))
|
||||
))))]
|
||||
(throw (ex-info (str "You are adding accounts without a valid type" )
|
||||
{:rows bad-types})))
|
||||
|
||||
(when-let [duplicate-rows (seq (->> rows
|
||||
(filter (fn [[account]]
|
||||
(not-empty account)))
|
||||
(group-by (fn [[account]]
|
||||
account))
|
||||
vals
|
||||
(filter #(> (count %) 1))
|
||||
(filter (fn [duplicates]
|
||||
(apply not= duplicates)))
|
||||
#_(map (fn [[[_ account]]]
|
||||
account))
|
||||
))]
|
||||
(throw (ex-info (str "You have duplicated rows with different values." )
|
||||
{:rows duplicate-rows}))))
|
||||
|
||||
(defn import-account-overrides [customer filename]
|
||||
(let [conn (d/connect uri)
|
||||
[header & rows] (-> filename (io/reader) csv/read-csv)
|
||||
[client-id] (first (d/query (-> {:query {:find ['?e]
|
||||
:in ['$ '?z]
|
||||
:where [['?e :client/code '?z]]}
|
||||
:args [(d/db (d/connect uri)) customer]})))
|
||||
_ (println client-id)
|
||||
headers (map read-string header)
|
||||
code->existing-account (by :account/numeric-code (map first (d/query {:query {:find ['(pull ?e [:account/numeric-code
|
||||
{:account/applicability [:db/ident]}
|
||||
:db/id])]
|
||||
:in ['$]
|
||||
:where ['[?e :account/name]]}
|
||||
:args [(d/db conn)]})))
|
||||
|
||||
existing-account-overrides (d/query (-> {:query {:find ['?e]
|
||||
:in ['$ '?client-id]
|
||||
:where [['?e :account-client-override/client '?client-id]]}
|
||||
:args [(d/db (d/connect uri)) client-id]}))
|
||||
|
||||
|
||||
rows (transduce (comp
|
||||
(map (fn [[_ account account-name override-name _ type]]
|
||||
[account account-name override-name type]))
|
||||
(filter (fn [[account]]
|
||||
(not-empty account))))
|
||||
conj
|
||||
[]
|
||||
rows)
|
||||
|
||||
_ (validate-account-rows rows code->existing-account)
|
||||
rows (vec (set rows))
|
||||
|
||||
txes (transduce
|
||||
(comp
|
||||
(mapcat (fn parse-map [[account account-name override-name type]]
|
||||
(let [code (some-> account
|
||||
not-empty
|
||||
Integer/parseInt)
|
||||
existing (code->existing-account code)]
|
||||
(cond (not code)
|
||||
[]
|
||||
|
||||
(and existing (or (#{:account-applicability/optional :account-applicability/customized}
|
||||
(:db/ident (:account/applicability existing)))
|
||||
(and (not-empty override-name)
|
||||
(not-empty account-name)
|
||||
(not= override-name account-name)
|
||||
)))
|
||||
[{:db/id (:db/id existing)
|
||||
:account/client-overrides [{:account-client-override/client client-id
|
||||
:account-client-override/name (or (not-empty override-name)
|
||||
(not-empty account-name))}]}]
|
||||
|
||||
(not existing)
|
||||
[{:account/applicability :account-applicability/customized
|
||||
:account/name account-name
|
||||
:account/account-set "default"
|
||||
:account/numeric-code code
|
||||
:account/code (str code)
|
||||
:account/type (if (str/blank? type)
|
||||
:account-type/expense
|
||||
(keyword "account-type" (str/lower-case type)))
|
||||
:account/client-overrides [{:account-client-override/client client-id
|
||||
:account-client-override/name (or (not-empty override-name)
|
||||
(not-empty account-name))}]}]
|
||||
:else
|
||||
[])))))
|
||||
|
||||
conj
|
||||
(mapv
|
||||
(fn [[x]]
|
||||
[:db/retractEntity x])
|
||||
existing-account-overrides)
|
||||
rows)]
|
||||
|
||||
@(d/transact conn txes)
|
||||
txes))
|
||||
|
||||
|
||||
|
||||
|
||||
(defn import-transactions-cleared-against [file]
|
||||
(let [[header & rows] (-> file (io/reader) csv/read-csv)
|
||||
@@ -418,5 +529,25 @@
|
||||
:body (pr-str {:message (.getMessage e)
|
||||
:error (.toString e)
|
||||
:data (ex-data e)})
|
||||
:headers {"Content-Type" "application/edn"}})))))
|
||||
:headers {"Content-Type" "application/edn"}}))))
|
||||
(wrap-json-response (POST "/account-overrides"
|
||||
{{files :file
|
||||
files-2 "file"
|
||||
client :client
|
||||
client-2 "client"} :params :as params
|
||||
user :identity}
|
||||
(let [files (or files files-2)
|
||||
client (or client client-2)
|
||||
{:keys [filename tempfile]} files]
|
||||
(assert-admin user)
|
||||
(try
|
||||
{:status 200
|
||||
:body (import-account-overrides client (.getPath tempfile))
|
||||
:headers {"Content-Type" "application/json"}}
|
||||
(catch Exception e
|
||||
(println e)
|
||||
{:status 500
|
||||
:body {:message (.getMessage e)
|
||||
:data (ex-data e)}
|
||||
:headers {"Content-Type" "application/json"}}))))))
|
||||
wrap-secure))
|
||||
|
||||
@@ -36,10 +36,36 @@
|
||||
{:status 200
|
||||
:headers {"Content-Type" "application/edn"}
|
||||
:body (pr-str (yodlee/get-accounts)) }))
|
||||
(POST "/accounts/:id" {:keys [query-params identity] {:keys [id]} :route-params :as request}
|
||||
|
||||
(GET "/provider-accounts" {:keys [query-params identity] :as request}
|
||||
(assert-admin identity)
|
||||
(let [[session token] (yodlee/get-access-token)]
|
||||
{:status 200
|
||||
:headers {"Content-Type" "application/edn"}
|
||||
:body (pr-str (yodlee/update-yodlee (Long/parseLong id))) })))
|
||||
:body (pr-str (yodlee/get-provider-accounts-with-accounts)) }))
|
||||
(POST "/reauthenticate/:id" {:keys [query-params identity] {:keys [id]} :route-params
|
||||
data :edn-params
|
||||
:as request}
|
||||
(assert-admin identity)
|
||||
(try
|
||||
(let [[session token] (yodlee/get-access-token)]
|
||||
{:status 200
|
||||
:headers {"Content-Type" "application/edn"}
|
||||
:body (pr-str (yodlee/reauthenticate (Long/parseLong id) data)) })
|
||||
(catch Exception e
|
||||
{:status 500
|
||||
:headers {"Content-Type" "application/edn"}
|
||||
:body (pr-str {:message (.getMessage e)
|
||||
:error (.toString e)})})))
|
||||
(POST "/provider-accounts/:id" {:keys [query-params identity] {:keys [id]} :route-params :as request}
|
||||
(assert-admin identity)
|
||||
(try
|
||||
(let [[session token] (yodlee/get-access-token)]
|
||||
{:status 200
|
||||
:headers {"Content-Type" "application/edn"}
|
||||
:body (pr-str (yodlee/update-yodlee (Long/parseLong id))) })
|
||||
(catch Exception e
|
||||
{:status 400
|
||||
:headers {"Content-Type" "application/edn"}
|
||||
:body (pr-str e)}))))
|
||||
wrap-secure))
|
||||
|
||||
Reference in New Issue
Block a user