(ns auto-ap.ssr.ledger.report-table (:require [auto-ap.ssr.components :as com] [auto-ap.time :as atime] [clj-time.coerce :as coerce] [clojure.string :as str] [hiccup.util :as hu] [iol-ion.query :as query])) (defn cell [{:keys [width investigate-url other-style]} c] (let [cell-contents (cond (= :dollar (:format c)) (format "$%,.2f" (if (query/dollars-0? (:value c)) 0.0 (:value c))) (= :percent (:format c)) (format "%%%.1f" (if (query/dollars-0? (:value c)) 0.0 (* 100.0 (or (:value c) 0.0)))) :else (str (:value c))) cell-contents (if (:filters c) (com/link {:hx-get (hu/url investigate-url (cond-> {} (:numeric-code (:filters c)) (assoc :numeric-code (into [] (:numeric-code (:filters c)))) (inst? (:date-range (:filters c))) (assoc :end-date (atime/unparse-local (coerce/to-date-time (:date-range (:filters c))) atime/normal-date)) (:end (:date-range (:filters c))) (assoc :end-date (atime/unparse-local (coerce/to-date-time (:end (:date-range (:filters c)))) atime/normal-date)) (:start (:date-range (:filters c))) (assoc :start-date (atime/unparse-local (coerce/to-date-time (:start (:date-range (:filters c)))) atime/normal-date)) (:client-id (:filters c)) (assoc :client-id (:client-id (:filters c)))) )} cell-contents) cell-contents)] [:td.px-4.py-2 (cond-> {:style (cond-> {:width (str width "em")} other-style (merge other-style))} (:border c) (update :style (fn [s] (->> (:border c) (map (fn [b] [(keyword (str "border-" (name b))) "1px solid black"]) ) (into s)))) (:colspan c) (assoc :colspan (:colspan c)) (:align c) (assoc :align (:align c)) (= :dollar (:format c)) (assoc :align :right) (= :percent (:format c)) (assoc :align :right) (:bold c) (assoc-in [:style :font-weight] "bold") (:color c) (assoc-in [:style :color] (str "rgb(" (str/join "," (:color c)) ")")) true (assoc-in [:style :background-color] (str "rgb(" (str/join "," (or (:bg-color c) [255 255 255])) ")"))) cell-contents])) (defn cell-count [table] (let [counts (map count (:rows table))] (if (seq counts) (apply max counts) 0))) (defn table [{:keys [table widths investigate-url warning]}] (let [cell-count (cell-count table)] (com/content-card {:class "inline-block overflow-scroll"} [:div {:class "overflow-scroll h-[70vh] m-4 inline-block"} (when warning [:div.rounded.bg-red-50.text-red-800.p-4.m-2 warning]) (-> [:table {:class "text-sm text-left text-gray-500 dark:text-gray-400"} [:thead {:class "text-xs text-gray-800 uppercase bg-gray-50 dark:bg-gray-700 dark:text-gray-400 font-bold"} (map (fn [header-row header] (into [:tr {:class " dark:border-gray-600 hover:bg-gray-100 dark:hover:bg-gray-700"}] (map (fn [w header i] (cell {:width w :investigate-url investigate-url :other-style {:position "sticky" :top (* header-row (+ 22 18))}} header)) widths header (range)))) (range) (:header table))]] (conj (-> [:tbody {:style {}}] (into (for [[i row] (map vector (range) (:rows table))] [:tr {:class " dark:border-gray-600 hover:bg-gray-100 dark:hover:bg-gray-700"} (for [[i c] (map vector (range) (take cell-count (reduce (fn [[acc cnt] cur] (if (>= (+ cnt (:colspan cur 1)) cell-count) (reduced (conj acc cur)) [(conj acc cur) (+ cnt (:colspan cur 1))])) [[] 0] (concat row (repeat nil)))))] (cell {:investigate-url investigate-url} c))])) (conj [:tr (for [i (range cell-count)] (cell {:investigate-url investigate-url} {:value " "}))]))))]))) (defn concat-tables [tables] (let [[first & rest] tables] {:header (:header first) :rows (concat (:rows first) [[]] (mapcat (fn [table] (-> (:header table) (into (:rows table)) (conj []))) rest))}))