refactor
This commit is contained in:
@@ -93,6 +93,60 @@
|
||||
(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 :company :bill-entered :bill-rejected :added-on :exported-on :default-expense-account]
|
||||
all-vendors (by :vendor/name (d-vendors/get-graphql {}))
|
||||
all-clients (d-clients/get-all)
|
||||
all-clients (merge (by :client/code all-clients) (by :client/name all-clients))
|
||||
rows (->> (str/split excel-rows #"\n" )
|
||||
(map #(str/split % #"\t"))
|
||||
(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 :default-expense-account parse-default-expense-account))
|
||||
(map (parse-or-error :invoice-number parse-invoice-number))
|
||||
(map (parse-or-error :total parse-amount))
|
||||
(map (parse-or-error :date parse-date)))]
|
||||
rows))
|
||||
|
||||
(defn invoice-rows->transaction [rows]
|
||||
(->> rows
|
||||
(mapcat (fn [{:keys [vendor-id total client-id amount date invoice-number default-location default-expense-account check vendor]}]
|
||||
(let [invoice #:invoice {:db/id (.toString (java.util.UUID/randomUUID))
|
||||
:vendor vendor-id
|
||||
:client client-id
|
||||
:default-location default-location
|
||||
:default-expense-account default-expense-account
|
||||
:total total
|
||||
:outstanding-balance (if (= "Cash" check)
|
||||
0.0
|
||||
total)
|
||||
:status (if (= "Cash" check)
|
||||
:invoice-status/paid
|
||||
:invoice-status/unpaid)
|
||||
:invoice-number invoice-number
|
||||
:date (to-date date)
|
||||
:expense-accounts [#:invoice-expense-account {:expense-account-id (or default-expense-account (:vendor/default-expense-account vendor))
|
||||
:location default-location
|
||||
:amount total}]}
|
||||
payment (if (= :invoice-status/paid (:invoice/status invoice))
|
||||
#:invoice-payment {:invoice (:db/id invoice)
|
||||
:amount (:invoice/total invoice)
|
||||
:payment (remove-nils #:payment {:db/id (.toString (java.util.UUID/randomUUID))
|
||||
:vendor (:invoice/vendor invoice)
|
||||
:client (:invoice/client invoice)
|
||||
:type :payment-type/cash
|
||||
:amount (:invoice/total invoice)
|
||||
:status :payment-status/cleared
|
||||
:date (:invoice/date invoice)})}
|
||||
)]
|
||||
[invoice payment])))
|
||||
(filter identity)
|
||||
(map remove-nils)))
|
||||
|
||||
(defroutes routes
|
||||
(wrap-routes
|
||||
(context "/" []
|
||||
@@ -134,78 +188,36 @@
|
||||
(POST "/upload-integreat"
|
||||
{{:keys [excel-rows]} :edn-params user :identity}
|
||||
(assert-admin user)
|
||||
(let [columns [:raw-date :vendor-name :check :location :invoice-number :amount :company :bill-entered :bill-rejected :added-on :exported-on :default-expense-account]
|
||||
all-vendors (by :vendor/name (d-vendors/get-graphql {}))
|
||||
all-clients (d-clients/get-all)
|
||||
all-clients (merge (by :client/code all-clients) (by :client/name all-clients))
|
||||
rows (->> (str/split excel-rows #"\n" )
|
||||
(map #(str/split % #"\t"))
|
||||
(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 :default-expense-account parse-default-expense-account))
|
||||
(map (parse-or-error :invoice-number parse-invoice-number))
|
||||
(map (parse-or-error :total parse-amount))
|
||||
(map (parse-or-error :date parse-date)))
|
||||
error-rows (filter :errors rows)
|
||||
vendors-not-found (->> rows
|
||||
(let [parsed-invoice-rows (parse-invoice-rows excel-rows)
|
||||
existing-rows (->> (d-invoices/raw-graphql {})
|
||||
(filter (fn [i] (not= :invoice-status/voided (:invoice/status i))))
|
||||
(map (fn [{:keys [:invoice/vendor :invoice/client :invoice/invoice-number]}]
|
||||
[(:db/id vendor) (:db/id client) invoice-number]))
|
||||
set)
|
||||
grouped-rows (group-by
|
||||
(fn [i]
|
||||
(cond (seq (:errors i))
|
||||
:error
|
||||
|
||||
(existing-rows [(:vendor-id i) (:client-id i) (:invoice-number i)])
|
||||
:exists
|
||||
|
||||
:else
|
||||
:new))
|
||||
parsed-invoice-rows)
|
||||
|
||||
|
||||
vendors-not-found (->> parsed-invoice-rows
|
||||
(filter #(and (nil? (:vendor-id %))
|
||||
(not= "Cash" (:check %))))
|
||||
(map :vendor-name)
|
||||
set)
|
||||
get-dupe-keys (fn [i]
|
||||
(select-keys i [:invoice/vendor :invoice/client :invoice/invoice-number]))
|
||||
existing-rows (->> (d-invoices/raw-graphql {})
|
||||
(filter (fn [i] (not= :invoice-status/voided (:invoice/status i))))
|
||||
(map (fn [i] (-> i
|
||||
(update :invoice/client :db/id)
|
||||
(update :invoice/vendor :db/id))))
|
||||
(map get-dupe-keys)
|
||||
set)
|
||||
total-rows (->> (filter #(not (seq (:errors %))) rows)
|
||||
(map (fn [{:keys [vendor-id total client-id amount date invoice-number default-location default-expense-account check vendor]}]
|
||||
#:invoice {:db/id (.toString (java.util.UUID/randomUUID))
|
||||
:vendor vendor-id
|
||||
:client client-id
|
||||
:default-location default-location
|
||||
:default-expense-account default-expense-account
|
||||
:total total
|
||||
:outstanding-balance (if (= "Cash" check)
|
||||
0.0
|
||||
total)
|
||||
:status (if (= "Cash" check)
|
||||
:invoice-status/paid
|
||||
:invoice-status/unpaid)
|
||||
:invoice-number invoice-number
|
||||
:date (to-date date)
|
||||
:expense-accounts [#:invoice-expense-account {:expense-account-id (or default-expense-account (:vendor/default-expense-account vendor))
|
||||
:location default-location
|
||||
:amount total}]})))
|
||||
insert-rows (vec (->> total-rows
|
||||
(filter #(not (existing-rows (get-dupe-keys %) )))
|
||||
(mapcat (fn [i]
|
||||
(if (= :invoice-status/paid (:invoice/status i))
|
||||
[i #:invoice-payment {:invoice (:db/id i)
|
||||
:amount (:invoice/total i)
|
||||
:payment (remove-nils #:payment {:db/id (.toString (java.util.UUID/randomUUID))
|
||||
:vendor (:invoice/vendor i)
|
||||
:client (:invoice/client i)
|
||||
:type :payment-type/cash
|
||||
:amount (:invoice/total i)
|
||||
:status :payment-status/cleared
|
||||
:date (:invoice/date i)})}]
|
||||
[i])))
|
||||
(map remove-nils)))
|
||||
|
||||
inserted-rows @(d/transact (d/connect uri) insert-rows)
|
||||
already-imported-count (- (count total-rows) (count insert-rows))]
|
||||
|
||||
inserted-rows @(d/transact (d/connect uri) (invoice-rows->transaction (:new grouped-rows)))]
|
||||
{:status 200
|
||||
:body (pr-str {:imported (count total-rows)
|
||||
:already-imported already-imported-count
|
||||
: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-rows)})
|
||||
:errors (:error grouped-rows)})
|
||||
:headers {"Content-Type" "application/edn"}}))))
|
||||
wrap-secure))
|
||||
|
||||
Reference in New Issue
Block a user