218 lines
7.2 KiB
Clojure
218 lines
7.2 KiB
Clojure
(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]
|
||
[auto-ap.logging :as alog]))
|
||
|
||
(defn determine
|
||
[[header]]
|
||
(alog/info ::importing :header header)
|
||
(let [csv-type (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
|
||
|
||
(str/includes? (str header) "Business Unit")
|
||
:mission
|
||
|
||
(str/includes? (str header) "Document Number")
|
||
:philz
|
||
|
||
|
||
(str/includes? (str header) "DISCOUNT_MESSAGE")
|
||
:wismettac
|
||
|
||
(str/includes? (str header) "Status")
|
||
:ledyard
|
||
|
||
(str/includes? (str header) "Due Date")
|
||
:ledyard
|
||
|
||
(str/includes? (str header) "PARENT CUSTOMER NAME")
|
||
:worldwide
|
||
|
||
:else
|
||
nil)]
|
||
(alog/info ::csv-type-determined :type csv-type)
|
||
csv-type))
|
||
|
||
(defmulti parse-csv
|
||
determine
|
||
:default #_{:clj-kondo/ignore [:unused-binding]}
|
||
(fn default [rows]
|
||
nil))
|
||
|
||
(defn parse-date-fallover [d fmts]
|
||
(when-let [valid-fmt (->> fmts
|
||
(filter (fn [f]
|
||
(try
|
||
(u/parse-value :clj-time f d)
|
||
(catch Exception _
|
||
nil))
|
||
))
|
||
(first))]
|
||
(u/parse-value :clj-time valid-fmt d)))
|
||
|
||
(defmethod parse-csv :sysco-style-1
|
||
[rows]
|
||
(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]
|
||
|
||
(let [header (first rows)]
|
||
(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" "M/d/yyyy"])
|
||
:total (str/replace (get row "Original Amount") #"[,\$]" "")
|
||
:text (str/join " " (vals row))
|
||
:full-text (str/join " " (vals row))})))
|
||
conj
|
||
[]
|
||
rows)))
|
||
|
||
(defmethod parse-csv :mama-lus
|
||
[rows]
|
||
(transduce
|
||
(comp (drop 1)
|
||
(map (fn [[_ po-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 :mission
|
||
[rows]
|
||
(transduce
|
||
(comp (drop 1)
|
||
(map (fn [[ po-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 :philz
|
||
[rows]
|
||
(transduce
|
||
(comp
|
||
(filter (fn [[_ _ _ _ _ status _ _ _ ]]
|
||
(= status "Billed")))
|
||
(map (fn [[dt _ doc-number name _ _ _ _ amount :as row]]
|
||
{:vendor-code "PHILZ COFFEE, INC"
|
||
:customer-identifier name
|
||
:invoice-number doc-number
|
||
:date (some-> dt not-empty (parse-date-fallover ["MM/dd/yyyy"]))
|
||
:total (str/replace amount #"," "")
|
||
:text (str/join " " row)
|
||
:full-text (str/join " " row)}))
|
||
|
||
|
||
)
|
||
conj
|
||
[]
|
||
(drop 1 rows)))
|
||
|
||
(defmethod parse-csv :wismettac
|
||
[rows]
|
||
(transduce
|
||
(comp
|
||
(map (fn [[inv_number inv_dt total :as row]]
|
||
{:vendor-code "Wismettac"
|
||
:invoice-number inv_number
|
||
:date (some-> inv_dt not-empty (parse-date-fallover ["MM/dd/yyyy"]))
|
||
:total (str/replace total #"," "")
|
||
:text (str/join " " row)
|
||
:full-text (str/join " " row)}))
|
||
)
|
||
conj
|
||
[]
|
||
(drop 1 rows)))
|
||
|
||
(defmethod parse-csv :ledyard
|
||
[rows]
|
||
(transduce
|
||
(comp
|
||
(map (fn [[invoice-number date due amount standard :as row]]
|
||
{:vendor-code "Performance Food Group - LEDYARD"
|
||
:invoice-number invoice-number
|
||
:date (some-> date not-empty (parse-date-fallover ["MM/dd/yy"]))
|
||
:due (some-> due not-empty (parse-date-fallover ["MM/dd/yy"]))
|
||
:total (str/replace amount #"[\$,]" "")
|
||
:text (str/join " " row)
|
||
:full-text (str/join " " row)}))
|
||
)
|
||
conj
|
||
[]
|
||
(drop 1 rows)))
|
||
|
||
(defmethod parse-csv :worldwide
|
||
[rows]
|
||
(transduce
|
||
(comp
|
||
(map (fn [[_ customer-name _ inv date amount :as row]]
|
||
{:vendor-code "Worldwide Produce"
|
||
:customer-identifier customer-name
|
||
:invoice-number (str/replace inv #"[=\"]" "")
|
||
:date (some-> date not-empty (parse-date-fallover ["MM/dd/yy"]))
|
||
:total (str/replace amount #"[\$,]" "")
|
||
:text (str/join " " row)
|
||
:full-text (str/join " " row)}))
|
||
)
|
||
conj
|
||
[]
|
||
(drop 1 rows)))
|
||
|
||
#_{:clj-kondo/ignore [:unused-binding]}
|
||
(defmethod parse-csv nil
|
||
[rows]
|
||
nil)
|
||
|
||
(defn parse-file [file _]
|
||
(with-open [reader (io/reader file)]
|
||
(let [rows (csv/read-csv reader :separator \,)]
|
||
(parse-csv rows))))
|
||
|