diff --git a/src/clj/auto_ap/parse.clj b/src/clj/auto_ap/parse.clj index 8f3ce7cd..fb8ff478 100644 --- a/src/clj/auto_ap/parse.clj +++ b/src/clj/auto_ap/parse.clj @@ -17,23 +17,30 @@ (defn template-applies? [text {:keys [keywords]}] (every? #(re-find % text) keywords)) -(defn extract-template [text template] - (if (:multi template) - (mapcat - #(extract-template % (dissoc template :multi)) - (str/split text (:multi template))) +(defn extract-template + ([text template] + (if (:multi template) + (mapcat + #(extract-template % text (dissoc template :multi)) + (str/split text (:multi template))) - (when template - [(->> template - :extract - (reduce-kv - (fn [result k v] - (let [value (some-> (first (map second (re-seq v text))) - str/trim ) - [value-parser parser-params] (-> template :parser k)] - (assoc result k (u/parse-value value-parser parser-params value)))) - {:vendor-code (:vendor template) - :text text}))]))) + (extract-template text text template))) + ([text full-text template] + (when (and template + (or (not (:multi-match? template)) + (re-find (:multi-match? template) text ))) + [(->> template + :extract + (reduce-kv + (fn [result k v] + (let [value (some-> (or (first (map second (re-seq v text))) + (first (map second (re-seq v full-text)))) + str/trim ) + [value-parser parser-params] (-> template :parser k)] + (assoc result k (u/parse-value value-parser parser-params value)))) + {:vendor-code (:vendor template) + :text text + :full-text full-text}))]))) (defn parse [text] (reset! last-text text) @@ -96,7 +103,7 @@ ffirst)] (or fuzzy-match client-word-match))) -(defn best-location-match [client text] +(defn best-location-match [client text full-text] (or (->> client :client/location-matches (mapcat (fn [{:keys [:location-match/location :location-match/matches]}] @@ -104,5 +111,12 @@ (filter (fn [[location match]] (re-find (re-pattern (str "(?i)" match)) text)) ) first first) + (->> client + :client/location-matches + (mapcat (fn [{:keys [:location-match/location :location-match/matches]}] + (map (fn [match] [location match]) matches))) + (filter (fn [[location match]] (re-find (re-pattern (str "(?i)" match)) full-text)) ) + first + first) (:client/default-location client) (first (:client/locations client)))) diff --git a/src/clj/auto_ap/parse/csv.clj b/src/clj/auto_ap/parse/csv.clj index bfbf39c1..f70b7727 100644 --- a/src/clj/auto_ap/parse/csv.clj +++ b/src/clj/auto_ap/parse/csv.clj @@ -26,7 +26,7 @@ (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 invoice-number " " po-number) + :invoice-number (str po-number "-" invoice-number ) :date (u/parse-value :clj-time "MM/dd/yy HH:ss" invoice-date) :total value :text (str/join " " row)}))) diff --git a/src/clj/auto_ap/parse/templates.clj b/src/clj/auto_ap/parse/templates.clj index 1350a0fa..9c0c966b 100644 --- a/src/clj/auto_ap/parse/templates.clj +++ b/src/clj/auto_ap/parse/templates.clj @@ -48,7 +48,16 @@ :customer-identifier #"Bill To:[^\n]+\n\s*([\w ]+)" :invoice-number #"Invoice\s([\w\./]+)*" :total #"Total Invoice\s+([0-9.]+)"} - :parser {:date [:clj-time "MM/dd/yy"]}}]) + :parser {:date [:clj-time "MM/dd/yy"]}} + {:vendor "Southbay Fresh Produce" + :keywords [#"SOUTH BAY FRESH PRODUCE"] + :extract {:date #"^([0-9]+/[0-9]+/[0-9]+)" + :customer-identifier #"FAX:[^\n]+\n\s+([A-Za-z ]+)\s{2}" + :invoice-number #"^[0-9]+/[0-9]+/[0-9]+\s+(\d+)" + :total #"\$([0-9.]+)"} + :parser {:date [:clj-time "MM/dd/yyyy"]} + :multi #"\n" + :multi-match? #"^[0-9]+/[0-9]+/[0-9]+\s+(\d+)"}]) (def excel-templates [{:vendor "Isp Productions" diff --git a/src/clj/auto_ap/routes/invoices.clj b/src/clj/auto_ap/routes/invoices.clj index 6607cd40..e37b3be4 100644 --- a/src/clj/auto_ap/routes/invoices.clj +++ b/src/clj/auto_ap/routes/invoices.clj @@ -163,7 +163,7 @@ (let [clients (d-clients/get-all) _ (println imports) - transactions (reduce (fn [result {:keys [invoice-number customer-identifier total date vendor-code text] :as info}] + transactions (reduce (fn [result {:keys [invoice-number customer-identifier total date vendor-code text full-text] :as info}] (println "searching for" vendor-code) (let [[matching-vendor default-expense-account] (->> (d/query {:query {:find ['?vendor '?default-expense-account] @@ -175,7 +175,7 @@ _ (println matching-vendor) matching-client (parse/best-match clients customer-identifier) _ (println "New invoice matches client" matching-client) - matching-location (parse/best-location-match matching-client text ) + matching-location (parse/best-location-match matching-client text full-text) [existing-id existing-outstanding-balance existing-status import-status] (when (and matching-client matching-location) (->> (d/query (cond-> {:query {:find ['?e '?outstanding-balance '?status '?import-status2]