can import from excel now.
This commit is contained in:
@@ -0,0 +1,4 @@
|
||||
-- 1525382176 DOWN more-customer-fields
|
||||
ALTER TABLE companies drop column code;
|
||||
delete from invoices;
|
||||
delete from companies;
|
||||
20
migrator/migrations/1525382176-UP-more-customer-fields.sql
Normal file
20
migrator/migrations/1525382176-UP-more-customer-fields.sql
Normal file
@@ -0,0 +1,20 @@
|
||||
-- 1525382176 UP more-customer-fields
|
||||
ALTER TABLE companies ADD code varchar(255);
|
||||
|
||||
INSERT INTO companies (code, name, data)
|
||||
VALUES
|
||||
('BCBC', 'Brown Chicken Brown Cow', '{}'),
|
||||
('BSG', 'Bella Saratoga', '{}'),
|
||||
('CBC', 'Campbell Brewing Co', '{}'),
|
||||
('IBC', 'Iguanas Burritozilla', '{}'),
|
||||
('IBCBC', 'Shared CBC-IBC Expenses', '{}'),
|
||||
('KOG', 'Knock Out Grill & Bar', '{}'),
|
||||
('LFT', 'Lefty''s East Coast Pizzeria', '{}'),
|
||||
('MAM', 'Mama Mia''s', '{}'),
|
||||
('MLF', 'Mama Lu''s Foods', '{}'),
|
||||
('MPI', 'Moscini Pizza Inc', '{}'),
|
||||
('NBST', 'Nasch Bistro', '{}'),
|
||||
('NMKT', 'Naschmarkt', '{}'),
|
||||
('RCI', 'Roberto''s Cantina Inc', '{}'),
|
||||
('SIB', 'Sorelle Italian Bistro', '{}'),
|
||||
('TSL', 'The Socialight', '{}');
|
||||
@@ -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]}
|
||||
|
||||
@@ -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)]))
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"}
|
||||
|
||||
@@ -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])
|
||||
|
||||
79
src/cljs/auto_ap/views/pages/admin/excel-import.cljs
Normal file
79
src/cljs/auto_ap/views/pages/admin/excel-import.cljs
Normal 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]])]]]])])
|
||||
@@ -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]
|
||||
|
||||
Reference in New Issue
Block a user