can import from excel now.

This commit is contained in:
Bryce Covert
2018-05-03 15:23:10 -07:00
parent 65e65302bf
commit ea1e43d981
9 changed files with 192 additions and 5 deletions

View File

@@ -6,7 +6,33 @@
[auto-ap.parse :as parse]
[auto-ap.routes.utils :refer [wrap-secure]]
[compojure.core :refer [GET POST context defroutes
wrap-routes]]))
wrap-routes]]
[clojure.string :as str]))
(defn reset-id [i]
(update i :invoice-number
(fn [n] (if (re-matches #"#+" n)
nil
n))))
(defn assoc-company-code [i]
(assoc i :company-code (first (str/split (:location i) #"-" ))))
(defn assoc-company [i companies]
(assoc i :company-id (or (-> i
:company-code
companies
:id)
(-> i
:company
companies
:id))))
(defn assoc-vendor [i vendors]
(assoc i :vendor-id (-> i
:vendor-name
vendors
:id)))
(defroutes routes
(wrap-routes
@@ -48,7 +74,50 @@
(invoices/import (parse/parse-file (.getPath tempfile) filename) companies vendors)
{:status 200
:body (pr-str (invoices/get-pending ((:query-params params ) "company")))
:headers {"Content-Type" "application/edn"}}))
:headers {"Content-Type" "application/edn"}}))
(POST "/upload-integreat"
{{:keys [excel-rows]} :edn-params}
(let [columns [:date :vendor-name :check :location :invoice-number :amount :company :bill-entered :bill-rejected :added-on :exported-on]
all-vendors (reduce
(fn [x y]
(assoc x (:name y) y))
{}
(vendors/get-all))
all-companies (reduce
(fn [x y]
(-> x
(assoc (:code y) y)
(assoc (:name y) y)))
{}
(companies/get-all))
rows (->> (str/split excel-rows #"\n" )
(map #(str/split % #"\t"))
(map #(into {} (map (fn [c k] [k c] ) % columns)))
(map reset-id)
(map assoc-company-code)
(map #(assoc-company % all-companies))
(map #(assoc-vendor % all-vendors))
(map (fn [{:keys [vendor-id company-id amount date invoice-number]}]
{:vendor-id vendor-id
:company-id company-id
:total (Double/parseDouble (second
(re-matches #"[^0-9\.]*([0-9\.]+)[^0-9\.]*" amount)))
:imported true
:status "unpaid"
:invoice-number invoice-number
:date (parse/parse-value :clj-time "MM/dd/yyyy" date )
}))
)]
(invoices/insert-multi! rows)
{:status 200
:body (pr-str rows)
:headers {"Content-Type" "application/edn"}}))
;; Removing the export view for now...
#_(wrap-json-response (GET "/export" {:keys [query-params]}

View File

@@ -8,6 +8,7 @@
(bidi/match-route routes/routes url))
(defn- dispatch-route [matched-route]
(println matched-route)
(re-frame/dispatch [:auto-ap.events/set-active-page (:handler matched-route)]))

View File

@@ -6,7 +6,8 @@
"admin/" {"" :admin
"companies" :admin-companies
"reminders" :admin-reminders
"vendors" :admin-vendors}
"vendors" :admin-vendors
"excel-import" :admin-excel-import}
"invoices/" {"" :invoices
"import" :import-invoices
"unpaid" :unpaid-invoices

View File

@@ -18,6 +18,7 @@
:paid-invoices :left-panel
:admin :admin-left-panel
:admin-companies :admin-left-panel
:admin-excel-import :admin-left-panel
:admin-vendors :admin-left-panel
:admin-reminders :admin-left-panel
:new-invoice :blank} page))
@@ -94,7 +95,15 @@
[:span {:class "icon"}
[:i {:class "fa fa-star-o"}]]
[:span {:class "name"} "Reminders"]]]]]
[:span {:class "name"} "Reminders"]]]]
[:p.menu-label "Import"]
[:ul.menu-list
[:li.menu-item
[:a {:href (bidi/path-for routes/routes :admin-excel-import) , :class (str "item" (active-when= ap :admin-excel-import))}
[:span {:class "icon"}
[:i {:class "fa fa-download"}]]
[:span {:class "name"} "Excel Invoices"]]]]]
[:div.left-nav
[:div {:class "compose has-text-centered"}

View File

@@ -13,6 +13,7 @@
[auto-ap.views.pages.unpaid-invoices :refer [unpaid-invoices-page]]
[auto-ap.views.pages.new-invoice :refer [new-invoice-page]]
[auto-ap.views.pages.import-invoices :refer [import-invoices-page]]
[auto-ap.views.pages.admin.excel-import :refer [admin-excel-import-page]]
[auto-ap.views.pages.paid-invoices :refer [paid-invoices-page]]
[cljs.reader :as edn]
[cljsjs.dropzone :as dz]
@@ -42,6 +43,9 @@
(defmethod active-page :admin-reminders []
[admin-reminders-page])
(defmethod active-page :admin-excel-import []
[admin-excel-import-page])
(defmethod active-page :unpaid-invoices []
[unpaid-invoices-page])

View File

@@ -0,0 +1,79 @@
(ns auto-ap.views.pages.admin.excel-import
(:require-macros [cljs.core.async.macros :refer [go]])
(:require [re-frame.core :as re-frame]
[reagent.core :as reagent]
[auto-ap.subs :as subs]
[auto-ap.events.admin.companies :as events]
[auto-ap.entities.companies :as entity]
[auto-ap.views.utils :refer [login-url dispatch-value-change bind-field horizontal-field dispatch-event]]
[cljs.reader :as edn]
[auto-ap.routes :as routes]
[bidi.bidi :as bidi]))
(re-frame/reg-sub
::excel-import
(fn [db]
(::excel-import db)))
(re-frame/reg-event-db
::change
(fn [db [_ field v]]
(assoc-in db (into [::excel-import] field) v)))
(re-frame/reg-event-db
::edit
(fn [db [_ field v]]
(assoc db ::excel-import nil )
db))
(re-frame/reg-event-fx
::save
(fn [{:keys [db]}]
(let [excel-import (::excel-import db)]
{:http {:token (:user db)
:method :post
:body (pr-str excel-import)
:headers {"Content-Type" "application/edn"}
:uri (str "/api/invoices/upload-integreat")
:on-success [::save-complete]
:on-error [::save-error]}})))
(re-frame/reg-event-fx
::save-complete
(fn [{:keys [db]} [_ rows]]
{:dispatch [::edit nil]
:db (assoc-in db [::excel-import :rows] rows)}))
(re-frame/reg-event-fx
::save-error
(fn [{:keys [db]}]
{:dispatch [::change [:error] true]}))
(defn admin-excel-import-page []
[:div
(let [excel-import-data @(re-frame/subscribe [::excel-import])]
[:div
[:h1.title "Import Invoices from Integreat Excel"]
[bind-field
[:textarea.textarea {:rows "20"
:field :excel-rows
:type "text"
:event ::change
:subscription excel-import-data}]]
[:button.button.is-large.is-pulled-right.is-primary {:on-click (dispatch-event [::save])} "Import"]
[:div
[:table.table.is-fullwidth
[:thead
[:td "Date"]
[:td "Invoice #"]
[:td "Vendor"]
[:td "Company"]]
[:tbody
(for [{:keys [invoice-number date vendor-name company]} (:rows excel-import-data)]
[:tr
[:td date]
[:td invoice-number]
[:td vendor-name]
[:td company]])]]]])])

View File

@@ -34,7 +34,7 @@
(when d
(format/unparse pretty-long d)))
(defmulti do-bind (fn [_ {:keys [type]}]
(defmulti do-bind (fn [a {:keys [type] :as x}]
type))
(defmethod do-bind "select" [dom {:keys [field subscription event class value spec] :as keys} & rest]