Files
integreat/src/clj/auto_ap/parse/csv.clj

195 lines
6.4 KiB
Clojure
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
(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]
[clojure.tools.logging :as log]))
(defn determine
[[header]]
(log/info "Importing with 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
:else
nil)]
(log/info "csv type was determined to be" 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/yyyy"]))
:due (some-> due 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)))
#_{: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))))