(ns auto-ap.parse.csv (:require [auto-ap.parse.util :as u] [clojure.data.csv :as csv] [clojure.java.io :as io] [clojure.string :as str])) (defn determine [[header :as z]] (prn header) (doto (cond (str/includes? (second header) "Customer's PO No.") :mama-lus (str/includes? (str header) "Ship-To Number") :sysco-style-2 (str/includes? (str header) "Closed Date") :sysco-style-1 :else nil) println)) (defmulti parse-csv determine :default (fn default [rows] nil)) (defn parse-date-fallover [d fmts] (if-let [valid-fmt (->> fmts (filter (fn [f] (try (u/parse-value :clj-time f d) (catch Exception e nil)) )) (first))] (u/parse-value :clj-time valid-fmt d))) (defmethod parse-csv :sysco-style-1 [rows] (println "Importing Sysco-styled 1") (let [header (first rows)] (transduce (comp (drop 1) (map (fn [row] (into {} (map vector header row)))) (filter (fn [row] (and (not (str/blank? (get row "Invoice Date"))) (not (str/blank? (get row "Orig Amt"))) (not (str/blank? (get row "Inv #")))))) (map (fn [row] {:vendor-code nil :customer-identifier nil :invoice-number (get row "Inv #") :date (parse-date-fallover (get row "Invoice Date") ["M/d/yyyy"]) :total (str/replace (get row "Orig Amt") #"[,\$]" "") :text (str/join " " (vals row)) :full-text (str/join " " (vals row))}))) conj [] rows))) (defmethod parse-csv :sysco-style-2 [rows] (println "Importing Sysco-styled 1") (let [header (first rows)] (doto (transduce (comp (drop 1) (map (fn [row] (into {} (map vector header row)))) (map (fn [row] {:vendor-code nil :customer-identifier (str (get row "Ship-To Name") " " (or (get row "Ship-To Number") (get row "\"Ship-To Number\""))) :invoice-number (str/trim (get row "Invoice Number")) :date (parse-date-fallover (get row "Invoice Date") ["yyyy-MM-dd"]) :total (str/replace (get row "Original Amount") #"[,\$]" "") :text (str/join " " (vals row)) :full-text (str/join " " (vals row))}))) conj [] rows) println))) (defmethod parse-csv :mama-lus [rows] (transduce (comp (drop 1) (map (fn [[_ po-number despatch-number invoice-number invoice-date customer value :as row]] {:vendor-code "Mama Lu's Foods" :customer-identifier customer :invoice-number (str po-number "-" invoice-number ) :date (parse-date-fallover invoice-date ["M/d/yyyy HH:ss" "M/d/yyyy HH:mm:ss aa" "M/d/yyyy"]) :total (str/replace value #"," "") :text (str/join " " row) :full-text (str/join " " row)}))) conj [] rows)) (defmethod parse-csv nil [rows] nil) (defn parse-file [file filename] (with-open [reader (io/reader file)] (let [rows (csv/read-csv reader :separator \,)] (parse-csv rows))))