adds export button.
This commit is contained in:
@@ -4,16 +4,15 @@
|
|||||||
[auto-ap.datomic :refer [conn]]
|
[auto-ap.datomic :refer [conn]]
|
||||||
[auto-ap.graphql.utils :refer [<-graphql]]
|
[auto-ap.graphql.utils :refer [<-graphql]]
|
||||||
[auto-ap.time :as atime]
|
[auto-ap.time :as atime]
|
||||||
[auto-ap.utils :refer [dollars-0?]]
|
[auto-ap.utils :refer [by dollars-0?]]
|
||||||
[clj-pdf.core :as pdf]
|
[clj-pdf.core :as pdf]
|
||||||
[clojure.java.io :as io]
|
[clojure.java.io :as io]
|
||||||
[clojure.string :as str]
|
[clojure.string :as str]
|
||||||
[clojure.walk :refer [postwalk]]
|
|
||||||
[config.core :refer [env]]
|
[config.core :refer [env]]
|
||||||
[datomic.api :as d]
|
[datomic.api :as d])
|
||||||
[clojure.tools.logging :as log])
|
|
||||||
(:import
|
(:import
|
||||||
(java.io ByteArrayOutputStream)
|
(java.io ByteArrayOutputStream)
|
||||||
|
(java.text DecimalFormat)
|
||||||
(java.util UUID)))
|
(java.util UUID)))
|
||||||
|
|
||||||
(defn distribute [nums]
|
(defn distribute [nums]
|
||||||
@@ -99,28 +98,6 @@
|
|||||||
"ZZZZZZ"
|
"ZZZZZZ"
|
||||||
(:location x))]))))
|
(:location x))]))))
|
||||||
|
|
||||||
(defn expand [data]
|
|
||||||
(postwalk (fn [x]
|
|
||||||
(cond
|
|
||||||
(map-entry? x)
|
|
||||||
x
|
|
||||||
|
|
||||||
(sequential? x)
|
|
||||||
(vec (mapcat (fn [r]
|
|
||||||
(cond (and (sequential? r)
|
|
||||||
(= :<> (first r)))
|
|
||||||
(filter identity (rest r))
|
|
||||||
|
|
||||||
:else
|
|
||||||
[r]))
|
|
||||||
x))
|
|
||||||
|
|
||||||
:else
|
|
||||||
x
|
|
||||||
))
|
|
||||||
data))
|
|
||||||
|
|
||||||
|
|
||||||
(defn aggregate-accounts [pnl-data]
|
(defn aggregate-accounts [pnl-data]
|
||||||
(reduce (fnil + 0.0) 0.0 (map :amount (:data pnl-data))))
|
(reduce (fnil + 0.0) 0.0 (map :amount (:data pnl-data))))
|
||||||
|
|
||||||
@@ -172,323 +149,261 @@
|
|||||||
(set)
|
(set)
|
||||||
(sort-by :numeric-code)))
|
(sort-by :numeric-code)))
|
||||||
|
|
||||||
(defn subtotal-row [pnl-data sales-pnl-data title]
|
(defn subtotal-row [pnl-data title]
|
||||||
(let [raw (map
|
(into [{:value title
|
||||||
(fn [p]
|
:bold true}]
|
||||||
(aggregate-accounts (filter-period pnl-data p)))
|
(map
|
||||||
(-> pnl-data :args :periods))
|
(fn [p]
|
||||||
sales (map
|
{:format :dollar
|
||||||
(fn [p]
|
:value (aggregate-accounts (filter-period pnl-data p))})
|
||||||
(aggregate-accounts (filter-period sales-pnl-data p)))
|
(-> pnl-data :args :periods))))
|
||||||
(-> pnl-data :args :periods))
|
|
||||||
deltas (->> raw
|
|
||||||
(partition-all 2)
|
|
||||||
(map (fn [[a b]]
|
|
||||||
(- b
|
|
||||||
a))))]
|
|
||||||
(into [title]
|
|
||||||
(->> raw
|
|
||||||
(map (fn [s r]
|
|
||||||
[r (if (dollars-0? s)
|
|
||||||
0.0
|
|
||||||
(/ r s))])
|
|
||||||
sales)
|
|
||||||
(partition-all 2)
|
|
||||||
(mapcat (fn [d [[a a-sales] [b b-sales]]]
|
|
||||||
[a a-sales b b-sales d]
|
|
||||||
)
|
|
||||||
deltas)))))
|
|
||||||
|
|
||||||
(defn location-summary-table [pnl-data]
|
(defn calc-percent-of-sales [table pnl-data]
|
||||||
|
(let [sales-pnl-data (filter-categories pnl-data [:sales])
|
||||||
(let [sales-data (filter-categories pnl-data [:sales])]
|
sales (map
|
||||||
[(subtotal-row (filter-categories pnl-data [:sales])
|
(fn [p]
|
||||||
sales-data
|
(aggregate-accounts (filter-period sales-pnl-data p)))
|
||||||
"Sales")
|
(-> pnl-data :args :periods))]
|
||||||
(subtotal-row (filter-categories pnl-data [:cogs ])
|
(->> table
|
||||||
sales-data
|
(map (fn [[_ & values]]
|
||||||
"Cogs")
|
(map
|
||||||
|
(fn [v s]
|
||||||
|
{:format :percent
|
||||||
|
:value (if (dollars-0? s)
|
||||||
|
0.0
|
||||||
|
(/ (:value v) s))})
|
||||||
|
values sales))))))
|
||||||
|
|
||||||
(subtotal-row (filter-categories pnl-data [:payroll ])
|
(defn calc-deltas [table]
|
||||||
sales-data
|
(->> table
|
||||||
"Payroll")
|
(map (fn [[_ & values]]
|
||||||
|
(->> values
|
||||||
|
(partition 2 1)
|
||||||
|
(map (fn [[a b]]
|
||||||
|
{:format :dollar
|
||||||
|
:value (- (:value b)
|
||||||
|
(:value a))})))))))
|
||||||
|
|
||||||
(subtotal-row (-> pnl-data
|
(defn combine-tables [pnl-data table percent-of-sales deltas]
|
||||||
(filter-categories [:sales :payroll :cogs])
|
(map (fn [[title & row] percent-of-sales deltas ]
|
||||||
(negate #{:payroll :cogs}))
|
(let [deltas (cons nil deltas)]
|
||||||
sales-data
|
(into [title]
|
||||||
"Gross Profits")
|
(filter identity
|
||||||
|
(mapcat
|
||||||
|
(fn [v p d]
|
||||||
|
[v p d])
|
||||||
|
row
|
||||||
|
percent-of-sales
|
||||||
|
deltas)))
|
||||||
|
))
|
||||||
|
table
|
||||||
|
percent-of-sales
|
||||||
|
deltas))
|
||||||
|
|
||||||
(subtotal-row (filter-categories pnl-data [:controllable :fixed-overhead :ownership-controllable])
|
(defn headers [pnl-data header-title]
|
||||||
sales-data
|
(let [deltas (cons nil (repeat "Change"))
|
||||||
"Overhead")
|
big-header (into [{:value header-title
|
||||||
|
:bold true}]
|
||||||
|
(map-indexed (fn [i p]
|
||||||
|
{:value
|
||||||
|
(str (date->str (:start p))
|
||||||
|
" - "
|
||||||
|
(date->str (:end p)))
|
||||||
|
:colspan (if (= 0 i)
|
||||||
|
2
|
||||||
|
3)
|
||||||
|
:align :center
|
||||||
|
:bold true})
|
||||||
|
(:periods (:args pnl-data))))
|
||||||
|
sub-header (into [{:value ""}]
|
||||||
|
(filter identity
|
||||||
|
(mapcat
|
||||||
|
(fn [v p d]
|
||||||
|
[{:value "Amount"
|
||||||
|
:align :right
|
||||||
|
:bold true}
|
||||||
|
{:value "% Sales"
|
||||||
|
:align :right
|
||||||
|
:bold true}
|
||||||
|
(when d
|
||||||
|
{:value d
|
||||||
|
:align :right
|
||||||
|
:bold true})])
|
||||||
|
(:periods (:args pnl-data))
|
||||||
|
(:periods (:args pnl-data))
|
||||||
|
deltas)))]
|
||||||
|
[big-header
|
||||||
|
sub-header]))
|
||||||
|
|
||||||
(subtotal-row (-> pnl-data
|
(defn location-summary-table [pnl-data title]
|
||||||
(filter-categories [:sales :cogs :payroll :controllable :fixed-overhead :ownership-controllable])
|
(let [table [(subtotal-row (filter-categories pnl-data [:sales]) "Sales")
|
||||||
(negate #{:cogs :payroll :controllable :fixed-overhead :ownership-controllable}))
|
(subtotal-row (filter-categories pnl-data [:cogs ]) "Cogs")
|
||||||
sales-data
|
|
||||||
"Net Income")
|
(subtotal-row (filter-categories pnl-data [:payroll ]) "Payroll")
|
||||||
]))
|
|
||||||
|
(subtotal-row (-> pnl-data
|
||||||
|
(filter-categories [:sales :payroll :cogs])
|
||||||
|
(negate #{:payroll :cogs}))
|
||||||
|
"Gross Profits")
|
||||||
|
|
||||||
|
(subtotal-row (filter-categories pnl-data [:controllable :fixed-overhead :ownership-controllable])
|
||||||
|
"Overhead")
|
||||||
|
|
||||||
|
(subtotal-row (-> pnl-data
|
||||||
|
(filter-categories [:sales :cogs :payroll :controllable :fixed-overhead :ownership-controllable])
|
||||||
|
(negate #{:cogs :payroll :controllable :fixed-overhead :ownership-controllable}))
|
||||||
|
"Net Income")]
|
||||||
|
percent-of-sales (calc-percent-of-sales table pnl-data)
|
||||||
|
deltas (calc-deltas table)]
|
||||||
|
{:header (headers pnl-data title)
|
||||||
|
:rows (combine-tables pnl-data table percent-of-sales deltas)}))
|
||||||
|
|
||||||
|
|
||||||
(defn detail-sub-rows [pnl-data sales-data grouping]
|
(defn detail-rows [pnl-data grouping title]
|
||||||
(for [[grouping-name from to] grouping
|
(let [pnl-data (filter-categories pnl-data [grouping])
|
||||||
:let [pnl-data (filter-numeric-code pnl-data from to)
|
individual-accounts
|
||||||
account-codes (used-accounts pnl-data)]
|
(for [[grouping-name from to] (groupings grouping)
|
||||||
:when (seq account-codes)]
|
:let [pnl-data (filter-numeric-code pnl-data from to)
|
||||||
(->
|
account-codes (used-accounts pnl-data)]
|
||||||
[[(str "---" grouping-name "---")]]
|
:when (seq account-codes)
|
||||||
(into (for [{:keys [numeric-code name]} account-codes]
|
row (-> [[{:value (str "---" grouping-name "---")
|
||||||
(let [raw (map
|
:bold true}]]
|
||||||
(fn [p]
|
(into (for [{:keys [numeric-code name]} account-codes]
|
||||||
(-> pnl-data
|
(into [{:value name
|
||||||
(filter-numeric-code numeric-code numeric-code)
|
:bold true}]
|
||||||
(filter-period p)
|
(map
|
||||||
(aggregate-accounts)))
|
(fn [p]
|
||||||
|
{:format :dollar
|
||||||
|
:value (-> pnl-data
|
||||||
|
(filter-numeric-code numeric-code numeric-code)
|
||||||
|
(filter-period p)
|
||||||
|
(aggregate-accounts))})
|
||||||
|
|
||||||
(-> pnl-data :args :periods))
|
(-> pnl-data :args :periods))))))]
|
||||||
sales (map
|
row)]
|
||||||
(fn [p]
|
(-> [[{:value title
|
||||||
(-> sales-data
|
:bold true}]]
|
||||||
(filter-period p)
|
(into individual-accounts)
|
||||||
(aggregate-accounts)))
|
(conj (subtotal-row pnl-data title)))))
|
||||||
|
|
||||||
(-> pnl-data :args :periods))
|
(defn location-detail-table [pnl-data title]
|
||||||
deltas (->> raw
|
(let [table (-> []
|
||||||
(partition-all 2)
|
(into (detail-rows pnl-data
|
||||||
(map (fn [[a b]]
|
:sales
|
||||||
(- b
|
(str (:prefix pnl-data) " Sales")))
|
||||||
a))))]
|
(into (detail-rows pnl-data
|
||||||
(into [name]
|
:cogs
|
||||||
(->> raw
|
(str (:prefix pnl-data) " COGS")))
|
||||||
(map (fn [s r]
|
(into (detail-rows
|
||||||
[r (if (dollars-0? s)
|
pnl-data
|
||||||
0.0
|
:payroll
|
||||||
(/ r s))])
|
(str (:prefix pnl-data) " Payroll")))
|
||||||
sales)
|
(conj (subtotal-row (filter-categories pnl-data [:payroll :cogs])
|
||||||
(partition-all 2)
|
(str (:prefix pnl-data) " Prime Costs")))
|
||||||
(mapcat (fn [d [[a a-sales] [b b-sales]]]
|
(conj (subtotal-row (-> pnl-data
|
||||||
[a a-sales b b-sales d]
|
(filter-categories [:sales :payroll :cogs])
|
||||||
)
|
(negate #{:payroll :cogs}))
|
||||||
deltas)))))))))
|
(str (:prefix pnl-data) " Gross Profits")))
|
||||||
|
(into (detail-rows
|
||||||
(defn detail-rows [pnl-data grouping sales-data title]
|
pnl-data
|
||||||
(let [pnl-data (filter-categories pnl-data [grouping])]
|
:fixed-overhead
|
||||||
(-> [[title]]
|
(str (:prefix pnl-data) " Fixed Overhead")))
|
||||||
(into (detail-sub-rows pnl-data
|
(into (detail-rows
|
||||||
sales-data
|
pnl-data
|
||||||
(grouping groupings)))
|
:ownership-controllable
|
||||||
(conj (subtotal-row pnl-data sales-data title)))))
|
(str (:prefix pnl-data) " Ownership Controllable")))
|
||||||
|
(conj (subtotal-row (-> pnl-data
|
||||||
(defn location-detail-table [pnl-data]
|
(filter-categories [:controllable :fixed-overhead :ownership-controllable]))
|
||||||
(let [sales-data (filter-categories pnl-data [:sales])]
|
(str (:prefix pnl-data) " Overhead")))
|
||||||
(-> []
|
(conj (subtotal-row (-> pnl-data
|
||||||
(into (detail-rows pnl-data
|
(filter-categories [:controllable :fixed-overhead :ownership-controllable]))
|
||||||
:sales
|
(str (:prefix pnl-data) " Overhead")))
|
||||||
sales-data
|
(conj (subtotal-row (-> pnl-data
|
||||||
(str (:prefix pnl-data) " Sales")))
|
(filter-categories [:sales :cogs :payroll :controllable :fixed-overhead :ownership-controllable])
|
||||||
(into (detail-rows pnl-data
|
(negate #{:cogs :payroll :controllable :fixed-overhead :ownership-controllable}))
|
||||||
:cogs
|
(str (:prefix pnl-data) " Net Income"))))
|
||||||
sales-data
|
percent-of-sales (calc-percent-of-sales table pnl-data)
|
||||||
(str (:prefix pnl-data) " COGS")))
|
deltas (into [] (calc-deltas table))]
|
||||||
(into (detail-rows
|
{:header (headers pnl-data title)
|
||||||
pnl-data
|
:rows (combine-tables pnl-data table percent-of-sales deltas)}))
|
||||||
:payroll
|
|
||||||
sales-data
|
|
||||||
(str (:prefix pnl-data) " Payroll")))
|
|
||||||
(conj (subtotal-row (filter-categories pnl-data [:payroll :cogs])
|
|
||||||
sales-data
|
|
||||||
(str (:prefix pnl-data) " Prime Costs")))
|
|
||||||
(conj (subtotal-row (-> pnl-data
|
|
||||||
(filter-categories [:payroll :cogs])
|
|
||||||
(negate #{:payroll :cogs}))
|
|
||||||
sales-data
|
|
||||||
(str (:prefix pnl-data) " Gross Profits")))
|
|
||||||
(into (detail-rows
|
|
||||||
pnl-data
|
|
||||||
:fixed-overhead
|
|
||||||
sales-data
|
|
||||||
(str (:prefix pnl-data) " Fixed Overhead")))
|
|
||||||
(into (detail-rows
|
|
||||||
pnl-data
|
|
||||||
:ownership-controllable
|
|
||||||
sales-data
|
|
||||||
(str (:prefix pnl-data) " Ownership Controllable")))
|
|
||||||
(conj (subtotal-row (-> pnl-data
|
|
||||||
(filter-categories [:controllable :fixed-overhead :ownership-controllable]))
|
|
||||||
sales-data
|
|
||||||
(str (:prefix pnl-data) " Overhead")))
|
|
||||||
(conj (subtotal-row (-> pnl-data
|
|
||||||
(filter-categories [:controllable :fixed-overhead :ownership-controllable]))
|
|
||||||
sales-data
|
|
||||||
(str (:prefix pnl-data) " Overhead")))
|
|
||||||
(conj (subtotal-row (-> pnl-data
|
|
||||||
(filter-categories [:sales :cogs :payroll :controllable :fixed-overhead :ownership-controllable])
|
|
||||||
(negate #{:cogs :payroll :controllable :fixed-overhead :ownership-controllable}))
|
|
||||||
sales-data
|
|
||||||
(str (:prefix pnl-data) " Net Income"))))))
|
|
||||||
|
|
||||||
(defn summarize-pnl [pnl-data]
|
(defn summarize-pnl [pnl-data]
|
||||||
(try
|
{:summaries (for [[client-id location] (locations (:data pnl-data))]
|
||||||
{:summaries (for [[client-id location] (locations (:data pnl-data))]
|
(location-summary-table (-> pnl-data
|
||||||
(location-summary-table (-> pnl-data
|
(filter-client client-id)
|
||||||
(filter-client client-id)
|
(filter-location location))
|
||||||
(filter-location location))))
|
(str (-> pnl-data :clients-by-id (get client-id) :client/name) " (" location ") Summary")))
|
||||||
:details (for [[client-id location] (locations (:data pnl-data))]
|
:details (for [[client-id location] (locations (:data pnl-data))]
|
||||||
(location-detail-table (-> pnl-data
|
(location-detail-table (-> pnl-data
|
||||||
(filter-client client-id)
|
(filter-client client-id)
|
||||||
(filter-location location)
|
(filter-location location)
|
||||||
(assoc :prefix location))))}
|
(assoc :prefix location))
|
||||||
(catch Throwable e
|
(str (-> pnl-data :clients-by-id (get client-id) :client/name) " (" location ") Detail")))})
|
||||||
|
|
||||||
(println e))))
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
(defrecord PNLData [args data]
|
(defrecord PNLData [args data clients-by-id])
|
||||||
)
|
|
||||||
|
|
||||||
|
(defn cell->pdf [cell]
|
||||||
|
[:pdf-cell
|
||||||
|
(cond-> {}
|
||||||
|
(= :dollar (:format cell)) (assoc :align :right)
|
||||||
|
(= :percent (:format cell)) (assoc :align :right)
|
||||||
|
(:bold cell) (assoc :style :bold)
|
||||||
|
(:align cell) (assoc :align (:align cell))
|
||||||
|
(:colspan cell) (assoc :colspan (:colspan cell)))
|
||||||
|
|
||||||
|
(cond (= :dollar (:format cell))
|
||||||
|
(.format (DecimalFormat. "$###,###.00") (:value cell))
|
||||||
|
|
||||||
|
(= :percent (:format cell))
|
||||||
|
(.format (DecimalFormat. "0%") (:value cell))
|
||||||
|
|
||||||
|
:else
|
||||||
|
(str (:value cell)))])
|
||||||
|
|
||||||
|
(defn table->pdf [table]
|
||||||
|
(let [cell-count (apply max (map count (:rows table)))]
|
||||||
|
(-> [:pdf-table {:header (mapv
|
||||||
|
(fn [header]
|
||||||
|
(map cell->pdf header))
|
||||||
|
(:header table))
|
||||||
|
:cell-border false}
|
||||||
|
(into [70] (take (dec cell-count) (repeat 20)))]
|
||||||
|
|
||||||
|
(into
|
||||||
|
(for [row (:rows table)]
|
||||||
|
(into []
|
||||||
|
(for [cell (take cell-count (concat row (repeat nil)))]
|
||||||
|
(cell->pdf cell)
|
||||||
|
))))
|
||||||
|
(conj (take cell-count (repeat (cell->pdf {:value " "})))))))
|
||||||
(defn make-pnl [args data]
|
(defn make-pnl [args data]
|
||||||
|
|
||||||
(let [data (<-graphql data)
|
(let [data (<-graphql data)
|
||||||
args (<-graphql args)
|
args (<-graphql args)
|
||||||
|
clients (d/pull-many (d/db conn) '[:client/name :db/id] (:client-ids args))
|
||||||
data (->> data
|
data (->> data
|
||||||
:periods
|
:periods
|
||||||
(mapcat (fn [p1 p2]
|
(mapcat (fn [p1 p2]
|
||||||
(map
|
(map
|
||||||
(fn [a]
|
(fn [a]
|
||||||
(assoc a :period p1)
|
(assoc a :period p1)
|
||||||
)
|
)
|
||||||
(:accounts p2))
|
(:accounts p2))
|
||||||
)
|
)
|
||||||
(:periods args)))
|
(:periods args)))
|
||||||
report (PNLData. (assoc args :deltas true) data)
|
report (summarize-pnl (PNLData. (assoc args :deltas true) data (by :db/id clients)))
|
||||||
_ (clojure.pprint/pprint (summarize-pnl report))
|
output-stream (ByteArrayOutputStream.)]
|
||||||
output-stream (ByteArrayOutputStream.)
|
|
||||||
_ (println (:client_ids args))
|
|
||||||
clients (d/pull-many (d/db conn) '[:client/name] (:client-ids args))]
|
|
||||||
(pdf/pdf
|
(pdf/pdf
|
||||||
(expand
|
[{:left-margin 15 :right-margin 15 :top-margin 15 :bottom-margin 15 :size :letter
|
||||||
[{:left-margin 25 :right-margin 0 :top-margin 0 :bottom-margin 0 :size :letter}
|
:font {:size 8}}
|
||||||
[:heading (str "Profit and Loss - " (str/join ", " (map :client/name clients)))]
|
[:heading (str "Profit and Loss - " (str/join ", " (map :client/name clients)))]
|
||||||
#_(for [[client-id location] (locations data)]
|
(into [:paragraph]
|
||||||
^{:key (str client-id "-" location "-summary")}
|
(map table->pdf (:summaries report)))
|
||||||
(location-summary args data client-id location (:include-deltas data))
|
(into [:paragraph]
|
||||||
)
|
(map table->pdf (:details report)))]
|
||||||
#_(let [{:keys [bank-account paid-to client check date amount memo] {print-as :vendor/print-as vendor-name :vendor/name :as vendor} :vendor} check
|
|
||||||
df (DecimalFormat. "#,###.00")]
|
|
||||||
[:table {:num-cols 6 :border false :leading 11 :widths (distribute [2 2 2 2 2 2])}
|
|
||||||
[(let [{:keys [:client/name] {:keys [:address/street1 :address/city :address/state :address/zip]} :client/address} client]
|
|
||||||
[:cell {:colspan 4 } [:paragraph {:leading 14} name "\n" street1 "\n" (str city ", " state " " zip)] ])
|
|
||||||
(let [{:keys [:bank-account/bank-name :bank-account/bank-code] } bank-account]
|
|
||||||
[:cell {:colspan 6 :align :center} [:paragraph {:style :bold} bank-name] [:paragraph {:size 8 :leading 8} bank-code]])
|
|
||||||
[:cell {:colspan 2 :size 13}
|
|
||||||
check]]
|
|
||||||
|
|
||||||
[[:cell {:colspan 9}]
|
|
||||||
[:cell {:colspan 3 :leading -10} date]]
|
|
||||||
[[:cell {:colspan 12 :size 14}]
|
|
||||||
]
|
|
||||||
|
|
||||||
[[:cell {:size 13 :leading 13} "PAY"]
|
|
||||||
[:cell {:size 8 :leading 8 } "TO THE ORDER OF"]
|
|
||||||
[:cell {:colspan 7} (if (seq print-as)
|
|
||||||
print-as
|
|
||||||
vendor-name)]
|
|
||||||
[:cell {:colspan 3} amount]]
|
|
||||||
|
|
||||||
[[:cell {}]
|
|
||||||
[:cell {:colspan 8} (str " -- " word-amount " " (str/join "" (take (max
|
|
||||||
2
|
|
||||||
(- 95
|
|
||||||
(count word-amount)))
|
|
||||||
(repeat "-"))))
|
|
||||||
[:line {:line-width 0.15 :color [50 50 50]}]]
|
|
||||||
[:cell {:colspan 3}]]
|
|
||||||
|
|
||||||
|
|
||||||
[[:cell {:size 9 :leading 11.5} "\n\n\n\n\nMEMO"]
|
|
||||||
[:cell {:colspan 5 :leading 11.5} (split-memo memo)
|
|
||||||
[:line {:line-width 0.15 :color [50 50 50]}]]
|
|
||||||
[:cell {:colspan 6 } (if (:client/signature-file client)
|
|
||||||
[:image { :top-margin 90 :xscale 0.30 :yscale 0.30 :align :center}
|
|
||||||
|
|
||||||
(:client/signature-file client)]
|
|
||||||
[:spacer])]]
|
|
||||||
|
|
||||||
#_[
|
|
||||||
#_[:cell {:colspan 5} #_memo ]
|
|
||||||
#_[:cell {:colspan 6}]]
|
|
||||||
|
|
||||||
[[:cell {:colspan 2}]
|
|
||||||
[:cell {:colspan 10 :leading 30}
|
|
||||||
[:phrase {:size 18 :ttf-name "public/micrenc.ttf"} (str "c" check "c a" (:bank-account/routing bank-account) "a " (:bank-account/number bank-account) "c")]]]
|
|
||||||
[[:cell {:colspan 12 :leading 18} [:spacer]]]
|
|
||||||
[[:cell]
|
|
||||||
(into
|
|
||||||
[:cell {:colspan 9}]
|
|
||||||
(let [{:keys [:client/name]
|
|
||||||
{:keys [:address/street1 :address/street2 :address/city :address/state :address/zip ]} :client/address} client]
|
|
||||||
(filter identity
|
|
||||||
(list
|
|
||||||
[:paragraph " " name]
|
|
||||||
[:paragraph " " street1]
|
|
||||||
(when (not (str/blank? street2))
|
|
||||||
[:paragraph " " street2])
|
|
||||||
[:paragraph " " city ", " state " " zip]))))
|
|
||||||
[:cell {:colspan 2 :size 13}
|
|
||||||
check]]
|
|
||||||
|
|
||||||
[[:cell {:colspan 12 :leading 74} [:spacer]]]
|
|
||||||
|
|
||||||
[[:cell]
|
|
||||||
[:cell {:colspan 5} [:paragraph
|
|
||||||
" " vendor-name "\n"
|
|
||||||
" " (:address/street1 (:vendor/address vendor)) "\n"
|
|
||||||
(when (not (str/blank? (:address/street2 (:vendor/address vendor))))
|
|
||||||
(str " " (:address/street2 (:vendor/address vendor)) "\n")
|
|
||||||
)
|
|
||||||
" " (:address/city (:vendor/address vendor)) ", " (:address/state (:vendor/address vendor)) " " (:address/zip (:vendor/address vendor))]]
|
|
||||||
[:cell {:align :right}
|
|
||||||
"Paid to:\n"
|
|
||||||
"Amount:\n"
|
|
||||||
"Date:\n"]
|
|
||||||
|
|
||||||
[:cell {:colspan 5}
|
|
||||||
[:paragraph paid-to]
|
|
||||||
[:paragraph amount]
|
|
||||||
[:paragraph date]]]
|
|
||||||
|
|
||||||
[[:cell {:colspan 3} "Memo:"]
|
|
||||||
[:cell {:colspan 9} memo]]
|
|
||||||
|
|
||||||
[[:cell {:colspan 12} [:spacer]]]
|
|
||||||
[[:cell {:colspan 12} [:spacer]]]
|
|
||||||
[[:cell {:colspan 12} [:spacer]]]
|
|
||||||
[[:cell {:colspan 12} [:spacer]]]
|
|
||||||
|
|
||||||
[[:cell {:colspan 5}]
|
|
||||||
[:cell {:align :right :colspan 2}
|
|
||||||
"Check:\n"
|
|
||||||
"Vendor:\n"
|
|
||||||
"Company:\n"
|
|
||||||
"Bank Account:\n"
|
|
||||||
"Paid To:\n"
|
|
||||||
"Amount:\n"
|
|
||||||
"Date:\n"]
|
|
||||||
|
|
||||||
[:cell {:colspan 5}
|
|
||||||
[:paragraph check]
|
|
||||||
[:paragraph vendor-name]
|
|
||||||
[:paragraph (:client/name client)]
|
|
||||||
[:paragraph (:bank-account/bank-name bank-account)]
|
|
||||||
[:paragraph paid-to]
|
|
||||||
[:paragraph amount]
|
|
||||||
[:paragraph date]]]
|
|
||||||
[[:cell {:colspan 3} "Memo:"]
|
|
||||||
[:cell {:colspan 9} memo]]
|
|
||||||
])])
|
|
||||||
output-stream)
|
output-stream)
|
||||||
(.toByteArray output-stream)))
|
(.toByteArray output-stream)))
|
||||||
|
|
||||||
|
|||||||
@@ -898,7 +898,9 @@
|
|||||||
:type "checkbox"}]]]]
|
:type "checkbox"}]]]]
|
||||||
[:div.level-right
|
[:div.level-right
|
||||||
[:div.buttons
|
[:div.buttons
|
||||||
[:button.button.is-secondary {:on-click (dispatch-event [::export-pdf])} "Export"]
|
|
||||||
|
(when @(re-frame/subscribe [::subs/is-admin?])
|
||||||
|
[:button.button.is-secondary {:on-click (dispatch-event [::export-pdf])} "Export"])
|
||||||
[:button.button.is-primary "Run"]]
|
[:button.button.is-primary "Run"]]
|
||||||
|
|
||||||
]]
|
]]
|
||||||
|
|||||||
Reference in New Issue
Block a user