Add vendor pre-population for bulk code and individual edit forms

- Add vendor-changed HTMX handlers for both bulk code and individual edit
- Pre-populate default account at 100% when vendor is selected and no accounts exist
- Fix render-accounts-section to render from step-params correctly
- Change bulk code vendor-changed from hx-get to hx-post to include form data
- Add routes for vendor-changed endpoints
- Update e2e tests to cover vendor pre-population
- Run lein cljfmt fix across codebase
This commit is contained in:
2026-05-21 14:45:19 -07:00
parent 8bd0cee1b1
commit ba87805d4c
210 changed files with 8694 additions and 9627 deletions

View File

@@ -23,7 +23,6 @@
(str/includes? (str header) "Document Number")
:philz
(str/includes? (str header) "DISCOUNT_MESSAGE")
:wismettac
@@ -35,7 +34,7 @@
(str/includes? (str header) "PARENT CUSTOMER NAME")
:worldwide
:else
nil)]
(alog/info ::csv-type-determined :type csv-type)
@@ -44,18 +43,17 @@
(defmulti parse-csv
determine
:default #_{:clj-kondo/ignore [:unused-binding]}
(fn default [rows]
nil))
(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))]
(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
@@ -83,7 +81,7 @@
(defmethod parse-csv :sysco-style-2
[rows]
(let [header (first rows)]
(transduce
(comp (drop 1)
@@ -109,7 +107,7 @@
(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 )
: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)
@@ -122,10 +120,10 @@
[rows]
(transduce
(comp (drop 1)
(map (fn [[ po-number _ invoice-number invoice-date customer value :as row]]
(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 )
: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)
@@ -137,8 +135,8 @@
(defmethod parse-csv :philz
[rows]
(transduce
(comp
(filter (fn [[_ _ _ _ _ status _ _ _ ]]
(comp
(filter (fn [[_ _ _ _ _ status _ _ _]]
(= status "Billed")))
(map (fn [[dt _ doc-number name _ _ _ _ amount :as row]]
{:vendor-code "PHILZ COFFEE, INC"
@@ -147,10 +145,8 @@
:date (some-> dt not-empty (parse-date-fallover ["MM/dd/yyyy"]))
:total (str/replace amount #"," "")
:text (str/join " " row)
:full-text (str/join " " row)}))
:full-text (str/join " " row)})))
)
conj
[]
(drop 1 rows)))
@@ -158,15 +154,14 @@
(defmethod parse-csv :wismettac
[rows]
(transduce
(comp
(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)}))
)
:full-text (str/join " " row)})))
conj
[]
(drop 1 rows)))
@@ -174,36 +169,34 @@
(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)))
(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)))
(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

View File

@@ -6,42 +6,38 @@
[clojure.data.json :as json]
[config.core :refer [env]]
[clojure.java.io :as io]
[amazonica.aws.s3 :as s3])
)
[amazonica.aws.s3 :as s3]))
(defn template-applies? [text {:keys [keywords]}]
(every? #(re-find % text) keywords))
(defn extract [wb {:keys [extract vendor parser]}]
(if (fn? extract)
(extract wb vendor)
#_[(reduce-kv
(fn [invoice k [regex offset-row offset-column extract-regex]]
(assoc invoice k
(->> wb
(d/sheet-seq)
first
(d/cell-seq)
(filter (fn [cell]
(re-find regex (str (d/read-cell cell)))))
(map (fn [cell]
(let [address (.getAddress cell)
cell-value (str (d/read-cell (d/select-cell (.toString (CellAddress. (+ offset-row (.getRow address)) (+ offset-column (.getColumn address)) ))
(first (d/sheet-seq wb)))))
raw-result (if extract-regex
(second (re-find extract-regex cell-value))
cell-value)]
(if (get parser k)
(u/parse-value (first (get parser k) ) (second (get parser k) ) raw-result)
raw-result
))))
first)))
{:vendor-code vendor}
extract)]))
(fn [invoice k [regex offset-row offset-column extract-regex]]
(assoc invoice k
(->> wb
(d/sheet-seq)
first
(d/cell-seq)
(filter (fn [cell]
(re-find regex (str (d/read-cell cell)))))
(map (fn [cell]
(let [address (.getAddress cell)
cell-value (str (d/read-cell (d/select-cell (.toString (CellAddress. (+ offset-row (.getRow address)) (+ offset-column (.getColumn address))))
(first (d/sheet-seq wb)))))
raw-result (if extract-regex
(second (re-find extract-regex cell-value))
cell-value)]
(if (get parser k)
(u/parse-value (first (get parser k)) (second (get parser k)) raw-result)
raw-result))))
first)))
{:vendor-code vendor}
extract)]))
(defn extract-sheet-details [bucket object]
(doto
@@ -57,7 +53,7 @@
[file _]
(let [tmp-key (str "xls-invoice/import/" (java.util.UUID/randomUUID))
_ (with-open [f (io/input-stream file)]
(s3/put-object {:bucket-name (:data-bucket env)
(s3/put-object {:bucket-name (:data-bucket env)
:key tmp-key
:input-stream f}))
sheet (extract-sheet-details (:data-bucket env) tmp-key)
@@ -67,9 +63,6 @@
first
(extract sheet))))
(defn xls-date->date [f]
(when (not-empty f)
(let [f (Double/parseDouble f)

View File

@@ -8,11 +8,9 @@
(defmulti parse-value (fn [method _ _]
method))
(defmethod parse-value :trim-commas
[_ _ value]
(str/replace value #"," "")
)
(str/replace value #"," ""))
(defmethod parse-value :trim-commas-and-remove-dollars
[_ _ value]
(str/replace (str/replace value #"," "") #"\$" ""))
@@ -20,7 +18,7 @@
(defmethod parse-value :trim-commas-and-remove-dollars-and-invert-parentheses
[_ _ value]
(let [v (str/replace (str/replace value #"," "") #"\$" "")]
(if-let [[_ a ] (re-find #"\((.*)\)" v)]
(if-let [[_ a] (re-find #"\((.*)\)" v)]
(str "-" a)
v)))
@@ -39,13 +37,12 @@
[_ _ value]
(let [format "yyyy-MM-dd"
[month day year] (str/split (-> value
(str/replace #"\s+" " ")
)
[month day year] (str/split (-> value
(str/replace #"\s+" " "))
#"\s")
value (str "20" year "-" month "-" day) ]
(try
value (str "20" year "-" month "-" day)]
(try
(time/from-time-zone (f/parse (f/formatter format) value)
(time/time-zone-for-id "America/Los_Angeles"))
(catch Exception e
@@ -59,15 +56,14 @@
[format])]
(reduce
(fn [_ format]
(try
(try
(reduced (time/from-time-zone (f/parse (f/formatter format) value)
(time/time-zone-for-id "America/Los_Angeles")))
(catch Exception e
(alog/warn ::cant-parse-date :error e :raw-value (str value))
nil)))
nil
format)
))
format)))
(defmethod parse-value nil
[_ _ value]