progress on making it possible to import from excel.
This commit is contained in:
@@ -21,21 +21,25 @@
|
|||||||
(defn upsert-multi! [rows]
|
(defn upsert-multi! [rows]
|
||||||
(let [k (vec (map #(keyword (kebab->snake (name %))) [:company-id :vendor-id :invoice-number :total :date :imported]))
|
(let [k (vec (map #(keyword (kebab->snake (name %))) [:company-id :vendor-id :invoice-number :total :date :imported]))
|
||||||
column-names (str/join "," (map name k))]
|
column-names (str/join "," (map name k))]
|
||||||
(doseq [rows (partition-all 2000 rows)]
|
(reduce
|
||||||
(j/db-do-prepared (get-conn)
|
(fn [affected rows]
|
||||||
(sql/format {:with [[[:v (str "(" column-names ")")]
|
(+ affected
|
||||||
(helpers/values (->> rows
|
(first (j/db-do-prepared (get-conn)
|
||||||
(map clj->db )
|
(sql/format {:with [[[:v (str "(" column-names ")")]
|
||||||
(map (apply juxt k))))]]
|
(helpers/values (->> rows
|
||||||
:insert-into [[:invoices k]
|
(map clj->db )
|
||||||
{:select [:v.company-id :v.vendor-id :v.invoice-number :v.total (sql/raw "cast(v.date as timestamp)") :v.imported ]
|
(map (apply juxt k))))]]
|
||||||
:from [:v]
|
:insert-into [[:invoices k]
|
||||||
:left-join [[:invoices :exist]
|
{:select [:v.company-id :v.vendor-id :v.invoice-number :v.total (sql/raw "cast(v.date as timestamp)") :v.imported ]
|
||||||
[:and
|
:from [:v]
|
||||||
[:= :exist.invoice-number :v.invoice-number]
|
:left-join [[:invoices :exist]
|
||||||
[:= :exist.company-id :v.company-id]
|
[:and
|
||||||
[:= :exist.vendor-id :v.vendor-id]]]
|
[:= :exist.invoice-number :v.invoice-number]
|
||||||
:where [:= :exist.id nil] }] })))))
|
[:= :exist.company-id :v.company-id]
|
||||||
|
[:= :exist.vendor-id :v.vendor-id]]]
|
||||||
|
:where [:= :exist.id nil] }] })))))
|
||||||
|
0
|
||||||
|
(partition-all 2000 rows))))
|
||||||
|
|
||||||
(def base-query (sql/build :select :invoices.*
|
(def base-query (sql/build :select :invoices.*
|
||||||
:from :invoices))
|
:from :invoices))
|
||||||
|
|||||||
@@ -135,12 +135,16 @@
|
|||||||
:imported true
|
:imported true
|
||||||
:status "unpaid"
|
:status "unpaid"
|
||||||
:invoice-number invoice-number
|
:invoice-number invoice-number
|
||||||
:date date}))))]
|
:date date}))))
|
||||||
|
|
||||||
(invoices/upsert-multi! insert-rows)
|
inserted-row-count (invoices/upsert-multi! insert-rows)
|
||||||
|
already-imported-count (- (count insert-rows) inserted-row-count)]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
{:status 200
|
{:status 200
|
||||||
:body (pr-str {:imported (count insert-rows)
|
:body (pr-str {:imported inserted-row-count
|
||||||
|
:already-imported already-imported-count
|
||||||
:errors (map #(dissoc % :date) error-rows)})
|
:errors (map #(dissoc % :date) error-rows)})
|
||||||
:headers {"Content-Type" "application/edn"}}))
|
:headers {"Content-Type" "application/edn"}}))
|
||||||
|
|
||||||
|
|||||||
@@ -38,18 +38,26 @@
|
|||||||
:uri (str "/api/invoices/upload-integreat")
|
:uri (str "/api/invoices/upload-integreat")
|
||||||
:on-success [::save-complete]
|
:on-success [::save-complete]
|
||||||
:on-error [::save-error]}
|
:on-error [::save-error]}
|
||||||
:db (assoc-in db [::excel-import :rows] nil)})))
|
:db (-> db
|
||||||
|
(assoc-in [::excel-import :rows] nil)
|
||||||
|
(assoc-in [::excel-import :saving?] true))})))
|
||||||
|
|
||||||
(re-frame/reg-event-fx
|
(re-frame/reg-event-fx
|
||||||
::save-complete
|
::save-complete
|
||||||
(fn [{:keys [db]} [_ rows]]
|
(fn [{:keys [db]} [_ rows]]
|
||||||
{:dispatch [::edit nil]
|
{:dispatch [::edit nil]
|
||||||
:db (assoc-in db [::excel-import :rows] rows)}))
|
:db
|
||||||
|
(-> db
|
||||||
|
(assoc-in [::excel-import :rows] rows)
|
||||||
|
(assoc-in [::excel-import :saving?] false))}))
|
||||||
|
|
||||||
(re-frame/reg-event-fx
|
(re-frame/reg-event-fx
|
||||||
::save-error
|
::save-error
|
||||||
(fn [{:keys [db]}]
|
(fn [{:keys [db]}]
|
||||||
{:dispatch [::change [:error] true]}))
|
{:dispatch [::change [:error] true]
|
||||||
|
:db (-> db
|
||||||
|
(assoc-in [::excel-import :rows] nil)
|
||||||
|
(assoc-in [::excel-import :saving?] false))}))
|
||||||
|
|
||||||
(defn admin-excel-import-page []
|
(defn admin-excel-import-page []
|
||||||
[:div
|
[:div
|
||||||
@@ -63,12 +71,18 @@
|
|||||||
:event ::change
|
:event ::change
|
||||||
:subscription excel-import-data}]]
|
:subscription excel-import-data}]]
|
||||||
|
|
||||||
[:button.button.is-large.is-pulled-right.is-primary {:on-click (dispatch-event [::save])} "Import"]
|
[:button.button.is-large.is-pulled-right.is-primary {:on-click (dispatch-event [::save])
|
||||||
|
:class (when (:saving? excel-import-data)
|
||||||
|
"is-loading")
|
||||||
|
:disabled (when (:saving? excel-import-data) "disabled")} "Import"]
|
||||||
|
|
||||||
[:div.is-clearfix
|
[:div.is-clearfix
|
||||||
(when-let [imported (:imported (:rows excel-import-data))]
|
[:p
|
||||||
(str imported " rows imported."))
|
(when-let [imported (:imported (:rows excel-import-data))]
|
||||||
]
|
(str imported " rows imported."))]
|
||||||
|
[:p
|
||||||
|
(when-let [already-imported (:already-imported (:rows excel-import-data))]
|
||||||
|
(str already-imported " rows already imported."))]]
|
||||||
(when-let [errors (:errors (:rows excel-import-data))]
|
(when-let [errors (:errors (:rows excel-import-data))]
|
||||||
|
|
||||||
[:div
|
[:div
|
||||||
Reference in New Issue
Block a user