154 lines
5.5 KiB
Clojure
154 lines
5.5 KiB
Clojure
(ns auto-ap.ssr.search
|
|
(:require
|
|
[auto-ap.graphql.utils :refer [can-see-client?]]
|
|
[auto-ap.solr :as solr]
|
|
[auto-ap.ssr.utils :refer [html-response modal-response]]
|
|
[auto-ap.time :as atime]
|
|
[clojure.string :as str]
|
|
[com.brunobonacci.mulog :as mu]
|
|
[auto-ap.ssr.components :as com]
|
|
[auto-ap.ssr.svg :as svg]))
|
|
|
|
(defn try-cleanse-date [d]
|
|
(try
|
|
(or
|
|
(some-> (atime/parse-utc d atime/normal-date) (atime/unparse atime/solr-date))
|
|
(some-> (atime/parse-utc d atime/iso-date) (atime/unparse atime/solr-date))
|
|
d)
|
|
(catch Exception _
|
|
d)))
|
|
|
|
(defn try-parse-number [n]
|
|
(if (re-find #"^[\-]?\d+\.\d+$" n )
|
|
(str (with-precision 2
|
|
(some-> n
|
|
(Double/parseDouble)
|
|
bigdec
|
|
(.setScale 2 java.math.RoundingMode/HALF_UP)
|
|
(double))))
|
|
n))
|
|
|
|
|
|
(defn q->solr-q [q]
|
|
(let [matches (re-seq #"(?:\".*?\"|\S)+" q)]
|
|
(str/join " AND "
|
|
(->> matches
|
|
(map (fn [m]
|
|
(cond (= "payment" m)
|
|
"type:payment"
|
|
|
|
(= "invoice" m)
|
|
"type:invoice"
|
|
|
|
(= "transaction" m)
|
|
"type:transaction"
|
|
|
|
(= "journal-entry" m)
|
|
"type:journal-entry"
|
|
|
|
|
|
:else
|
|
(str "_text_:\"" (try-parse-number (try-cleanse-date m)) ""\"))))))))
|
|
|
|
|
|
(defn search-results [q id]
|
|
(into []
|
|
(filter (fn [d]
|
|
(can-see-client? id (first (:client_id d)))))
|
|
(solr/query solr/impl "invoices" {"query" (q->solr-q q)
|
|
"fields" "id, date, amount, type, description, number, client_code, client_id, vendor_name"})))
|
|
|
|
|
|
(defn search-results* [q id]
|
|
(let [results (search-results q id)]
|
|
[:div
|
|
(if (seq results)
|
|
[:div.flex.gap-8.flex-col
|
|
(for [doc results]
|
|
(com/card {}
|
|
[:div.flex.flex-col.gap-4
|
|
[:div.flex.items-center.p-2.gap-4.bg-gray-50.dark:bg-gray-800
|
|
[:div.h-8.w-8.p-2
|
|
(cond (= "transaction" (:type doc))
|
|
svg/bank
|
|
|
|
|
|
(= "invoice" (:type doc))
|
|
svg/accounting-invoice-mail
|
|
|
|
|
|
(= "payment" (:type doc))
|
|
svg/payments
|
|
|
|
(= "journal-entry" (:type doc))
|
|
svg/receipt
|
|
|
|
:else
|
|
nil)]
|
|
(clojure.string/capitalize (:type doc))
|
|
(com/pill {:color :primary}
|
|
"client: " (:client_code doc))
|
|
(com/pill {:color :secondary}
|
|
"amount: $" (first (:amount doc)))
|
|
(when-let [vendor-name (first (:vendor_name doc))]
|
|
(com/pill {:color :yellow}
|
|
"vendor: " vendor-name))
|
|
[:div
|
|
(com/link {:href (str "/" (cond (= "invoice"
|
|
(:type doc))
|
|
"invoices"
|
|
|
|
(= "transaction"
|
|
(:type doc))
|
|
"transactions"
|
|
|
|
(= "journal-entry"
|
|
(:type doc))
|
|
"ledger"
|
|
|
|
:else
|
|
"payments") "/?exact-match-id=" (:id doc))
|
|
:target "_blank"}
|
|
[:div.h-8.w-8.p-2
|
|
svg/external-link])]
|
|
]
|
|
|
|
|
|
[:div.px-4.pb-2
|
|
[:span
|
|
|
|
[:strong (atime/unparse (atime/parse (:date doc) atime/solr-date) atime/normal-date)]
|
|
": "
|
|
(str (or (first (:description doc))
|
|
(first (:number doc))))]]])
|
|
)]
|
|
[:div.block "No results found."])]))
|
|
|
|
(defn dialog-contents [request]
|
|
(if-let [q (get (:form-params request) "q")]
|
|
(html-response (search-results* q (:identity request)))
|
|
(modal-response
|
|
(com/modal {}
|
|
(com/modal-card {:class "w-full h-full"}
|
|
[:div.p-2 "Search"]
|
|
[:div#search.overflow-auto.space-y-6.p-2.w-full
|
|
|
|
(com/text-input {:id "search-input"
|
|
:type "search"
|
|
:placeholder "5/5/2034 Magheritas"
|
|
:name "q"
|
|
:hx-post "/search"
|
|
:hx-trigger "keyup changed delay:300ms, search"
|
|
:hx-target "#search-results"
|
|
:hx-indicator "#search"
|
|
:value (:q (:params request))
|
|
:autofocus true})
|
|
[:i.text-sm.text-gray-600.dark:text-gray-50 "Try dates, numbers, vendors. To filter to specific type, use 'invoice', 'transaction', 'journal-entry', 'payment'."]
|
|
#_[:style
|
|
".htmx-request #search-results {display: none} .htmx-request .htmx-indicator { display: block !important; }"]
|
|
[:div#search-results
|
|
]
|
|
[:div.loader.is-loading.big.htmx-indicator ]]
|
|
nil)))))
|
|
|