Sales summaries in slightly more detail

This commit is contained in:
2024-04-29 22:44:09 -07:00
parent 1b80712742
commit f25ddc2ee4
3 changed files with 320 additions and 79 deletions

View File

@@ -52,8 +52,236 @@
(filter (fn [sales-summary]
(= client-id (:db/id (:sales-summary/client sales-summary))))))))
(defn- get-fee [c date]
(- (or (ffirst (dc/q '[:find ?f
:in $ ?client ?d
:where
[?e :expected-deposit/client ?client]
[?e :expected-deposit/sales-date ?d]
[?e :expected-deposit/fee ?f]]
(dc/db conn)
c
date))
0.0)))
(defn get-payment-items [c date]
(->>
(dc/q '[:find ?processor ?type-name (sum ?total)
:with ?c
:in $ [?clients ?start-date ?end-date]
:where [(iol-ion.query/scan-sales-orders $ ?clients ?start-date ?end-date) [[?e _ ?sort-default] ...]]
[?e :sales-order/charges ?c]
[?c :charge/type-name ?type-name]
(or-join [?c ?processor]
(and [?c :charge/processor ?p]
[?p :db/ident ?processor])
(and
(not [?c :charge/processor])
[(ground :ccp-processor/na) ?processor]))
[?c :charge/total ?total]]
(dc/db conn)
[[c] date date])
(reduce
(fn [acc [processor type-name total]]
(update
acc
(cond (= type-name "CARD")
"Card Payments"
(= type-name "CASH")
"Cash Payments"
(#{"SQUARE_GIFT_CARD" "WALLET" "GIFT_CARD"} type-name)
"Gift Card Payments"
(#{:ccp-processor/toast
#_:ccp-processor/ezcater
#_:ccp-processor/koala
:ccp-processor/doordash
:ccp-processor/grubhub
:ccp-processor/uber-eats} processor)
"Food App Payments"
:else
"Unknown")
(fnil + 0.0)
total))
{})
(map (fn [[k v]]
{:db/id (str (java.util.UUID/randomUUID))
:sales-summary-item/category k
:ledger-mapped/amount (if (= "Card Payments" k)
(- v (get-fee c date))
v)
:ledger-mapped/ledger-side :ledger-side/debit}))))
(defn sales-summaries []
(defn get-discounts [c date]
(when-let [discount (ffirst (dc/q '[:find (sum ?discount)
:with ?e
:in $ [?clients ?start-date ?end-date]
:where [(iol-ion.query/scan-sales-orders $ ?clients ?start-date ?end-date) [[?e _ ?sort-default] ...]]
[?e :sales-order/discount ?discount]]
(dc/db conn)
[[c] date date]))]
{:db/id (str (java.util.UUID/randomUUID))
:sales-summary-item/category "Discounts"
:ledger-mapped/amount discount
:ledger-mapped/ledger-side :ledger-side/debit }))
(defn get-refund-items [c date]
(->>
(dc/q '[:find ?type-name (sum ?t)
:with ?e
:in $ [?clients ?start-date ?end-date]
:where
:where [(iol-ion.query/scan-sales-refunds $ ?clients ?start-date ?end-date) [[?e _ ?sort-default] ...]]
[?e :sales-refund/type ?type-name]
[?e :sales-refund/total ?t]]
(dc/db conn)
[[c] date date])
(reduce
(fn [acc [type-name total]]
(update
acc
(cond (= type-name "CARD")
"Card Refunds"
(= type-name "CASH")
"Cash Refunds"
:else
"Food App Refunds")
(fnil + 0.0)
total))
{})
(map (fn [[k v]]
{:db/id (str (java.util.UUID/randomUUID))
:sales-summary-item/category k
:ledger-mapped/amount v
:ledger-mapped/ledger-side :ledger-side/credit}))))
(defn get-fees [c date]
(when-let [fee (get-fee c date)]
{:db/id (str (java.util.UUID/randomUUID))
:sales-summary-item/category "Fees"
:ledger-mapped/amount fee
:ledger-mapped/ledger-side :ledger-side/debit}))
(defn- get-tax [c date]
{:db/id (str (java.util.UUID/randomUUID))
:ledger-mapped/ledger-side :ledger-side/credit
:ledger-mapped/amount
(or (ffirst (dc/q '[:find (sum ?tax)
:with ?e
:in $ [?clients ?start-date ?end-date]
:where [(iol-ion.query/scan-sales-orders $ ?clients ?start-date ?end-date) [[?e _ ?sort-default] ...]]
[?e :sales-order/tax ?tax]
#_[?e :sales-order/charges ?c]
#_[?c :charge/tax ?tax]]
(dc/db conn)
[[c] date date]))
0.0)})
(defn- get-tip [c date]
{:ledger-mapped/ledger-side :ledger-side/credit
:ledger-mapped/amount (or (ffirst (dc/q '[:find (sum ?tip)
:with ?c
:in $ [?clients ?start-date ?end-date]
:where [(iol-ion.query/scan-sales-orders $ ?clients ?start-date ?end-date) [[?e _ ?sort-default] ...]]
[?e :sales-order/charges ?c]
[?c :charge/tip ?tip]]
(dc/db conn)
[[c] date date]))
0.0)})
(defn- get-sales [c date]
(let [sales (->> (dc/q '[:find ?category (sum ?total) (sum ?tax) (sum ?discount)
:with ?e ?li
:in $ [?clients ?start-date ?end-date]
:where [(iol-ion.query/scan-sales-orders $ ?clients ?start-date ?end-date) [[?e _ ?sort-default] ...]]
[?e :sales-order/line-items ?li]
[(get-else $ ?li :order-line-item/category "Unknown") ?category]
[?li :order-line-item/total ?total]
[?li :order-line-item/tax ?tax]
[?li :order-line-item/discount ?discount]]
(dc/db conn)
[[c] date date]))]
(for [[category total tax discount] sales]
{:db/id (str (java.util.UUID/randomUUID))
:sales-summary-item/category category
:sales-summary-item/total total
:sales-summary-item/net (- (+ total discount) tax)
:sales-summary-item/tax tax
:sales-summary-item/discount discount
:ledger-mapped/ledger-side :ledger-side/credit
:ledger-mapped/amount (- (+ total discount) tax)
#_#_:ledger-mapped/account nil})))
(defn sales-summaries-v2 []
(doseq [[c client-code] (dc/q '[:find ?c ?client-code
:in $
:where [?c :client/code ?client-code]]
(dc/db conn))
{:sales-summary/keys [date] :db/keys [id]} (dirty-sales-summaries c)]
(mu/with-context {:client-code client-code
:date date}
(alog/info ::updating)
(let [result {:db/id id
:sales-summary/client c
:sales-summary/date date
:sales-summary/dirty false
:sales-summary/client+date [c date]
:sales-summary/sales-items
(conj (get-sales c date)
{:db/id (str (java.util.UUID/randomUUID))
:sales-summary-item/category "Returns"
:ledger-mapped/amount (or (ffirst (dc/q '[:find (sum ?r)
:with ?e
:in $ [?clients ?start-date ?end-date]
:where [(iol-ion.query/scan-sales-orders $ ?clients ?start-date ?end-date) [[?e _ ?sort-default] ...]]
[?e :sales-order/returns ?r]
#_[?e :sales-order/charges ?c]
#_[?c :charge/tax ?tax]]
(dc/db conn)
[[c] date date]))
0.0)
:ledger-mapped/ledger-side :ledger-side/debit})
:sales-summary/payment-items
(->> (get-payment-items c date)
(concat (get-refund-items c date))
(cons (get-discounts c date))
(cons (get-fees c date))
(filter identity))
:sales-summary/total-tax
(get-tax c date)
:sales-summary/total-tip
(get-tip c date)
#_#_:sales-summary/total-card-payments
(or (ffirst (dc/q '[:find (sum ?total)
:with ?c
:in $ [?clients ?start-date ?end-date]
:where [(iol-ion.query/scan-sales-orders $ ?clients ?start-date ?end-date) [[?e _ ?sort-default] ...]]
[?e :sales-order/charges ?c]
[?c :charge/type-name "CARD"]
[?c :charge/total ?total]]
(dc/db conn)
[[c] date date]))
0.0)
#_:sales-summary/total-unknown-processor-payments}]
(if (seq (:sales-summary/sales-items result))
(do
(alog/info ::upserting-summaries
:category-count (count (:sales-summary/sales-items result)))
@(dc/transact conn [[:upsert-entity result]]))
@(dc/transact conn [{:db/id id :sales-summary/dirty false}]))))))
(let [c (auto-ap.datomic/pull-attr (dc/db conn) :db/id [:client/code "NGCL" ])
date #inst "2024-04-14T00:00:00-07:00"]
(get-payment-items c date)
)
#_(defn sales-summaries-v1 []
(doseq [[c client-code] (dc/q '[:find ?c ?client-code
:in $
:where [?c :client/code ?client-code]]
@@ -100,9 +328,6 @@
0.0)
:sales-summary/sales-items
(for [[item-name category total tax discount] sales]
{:db/id (str (java.util.UUID/randomUUID))
:sales-summary-item/item-name item-name
@@ -110,6 +335,7 @@
:sales-summary-item/total total
:sales-summary-item/tax tax
:sales-summary-item/discount discount})
:sales-summary/total-tax
(or (ffirst (dc/q '[:find (sum ?tax)
@@ -268,14 +494,16 @@
:db/valueType :db.type/double
:db/cardinality :db.cardinality/one}])
(apply mark-dirty [:client/code "NGCL"] (last-n-days 14))
(apply mark-dirty [:client/code "NGDG"] (last-n-days 14))
(apply mark-dirty [:client/code "NGPG"] (last-n-days 14))
(apply mark-dirty [:client/code "NGCL"] (last-n-days 30))
(apply mark-dirty [:client/code "NGDG"] (last-n-days 30))
(apply mark-dirty [:client/code "NGPG"] (last-n-days 30))
(mark-all-dirty 50)
(delete-all)
(sales-summaries)
(sales-summaries-v2)
(dc/q '[:find (pull ?sos [* {:sales-summary/sales-items [*]}])
:in $
@@ -304,11 +532,13 @@
(dc/db conn)
[[(auto-ap.datomic/pull-attr (dc/db conn) :db/id [:client/code "NGCL"])] #inst "2024-04-11T00:00:00-07:00" #inst "2024-04-24T00:00:00-07:00"])
@(dc/transact conn [{:db/id :sales-summary/total-tax :db/ident :sales-summary/total-tax-legacy}
{:db/id :sales-summary/total-tip :db/ident :sales-summary/total-tip-legacy}])
)
(defn -main [& _]
(execute "sales-summaries" sales-summaries))
(execute "sales-summaries" sales-summaries-v2))

View File

@@ -44,9 +44,20 @@
:size :small}))]])
(def default-read '[:db/id
*
[:sales-summary/date :xform clj-time.coerce/from-date]
{:sales-summary/client [:client/code :client/name]}
*]) ;; TODO
{:sales-summary/total-tax [{[:ledger-mapped/ledger-side :xform iol-ion.query/ident] [:db/ident]}
:ledger-mapped/amount]}
{:sales-summary/total-tip [{[:ledger-mapped/ledger-side :xform iol-ion.query/ident] [:db/ident]}
:ledger-mapped/amount]}
{:sales-summary/sales-items [{[:ledger-mapped/ledger-side :xform iol-ion.query/ident] [:db/ident]}
:ledger-mapped/amount
:sales-summary-item/category]}
{:sales-summary/payment-items [{[:ledger-mapped/ledger-side :xform iol-ion.query/ident] [:db/ident]}
:ledger-mapped/amount
:sales-summary-item/category]}]) ;; TODO
(defn fetch-ids [db request]
(let [query-params (:parsed-query-params request)
@@ -96,7 +107,7 @@
[(->> (hydrate-results ids-to-retrieve db request))
matching-count]))
(defn get-debits [ss]
#_(defn get-debits [ss]
{:card-payments (+ (:sales-summary/total-card-payments ss 0.0)
(:sales-summary/total-card-fees ss 0.0)
(- (:sales-summary/total-card-refunds ss 0.0)))
@@ -117,6 +128,11 @@
:discounts (+ (:sales-summary/discount ss 0.0))
:returns (+ (:sales-summary/total-returns ss 0.0))})
(defn all-items [ss]
(->> [(:sales-summary/total-tax ss) (:sales-summary/total-tip ss)]
(into (:sales-summary/payment-items ss))
(into (:sales-summary/sales-items ss))))
(def grid-page
(helper/build {:id "entity-table"
:id-fn :db/id
@@ -159,25 +175,25 @@
:name "credits"
:sort-key "credits"
:render (fn [ss]
(let [total-debits (reduce + 0.0 (vals (get-debits ss)))
total-credits (+ (- (+ (reduce + 0.0 (map :sales-summary-item/total (:sales-summary/sales-items ss)))
(reduce + 0.0 (map :sales-summary-item/discount (:sales-summary/sales-items ss))))
(reduce + 0.0 (map :sales-summary-item/tax (:sales-summary/sales-items ss))))
(:sales-summary/total-tax ss 0.0)
(:sales-summary/total-tip ss 0.0))]
(let [total-debits (->> (all-items ss)
(filter #(= :ledger-side/debit (:ledger-mapped/ledger-side %)))
(map #(:ledger-mapped/amount % 0.0))
(reduce + 0.0))
total-credits (->> (all-items ss)
(filter #(= :ledger-side/credit (:ledger-mapped/ledger-side %)))
(map #(:ledger-mapped/amount % 0.0))
(reduce + 0.0))]
[:ul
(for [[n x] (group-by :sales-summary-item/category (:sales-summary/sales-items ss))]
[:li n ": " (format "$%,.2f" (- (+ (reduce + 0.0 (map :sales-summary-item/total x))
(reduce + 0.0 (map :sales-summary-item/discount x)))
(reduce + 0.0 (map :sales-summary-item/tax x))))])
[:li "Sales subtotal: " (format "$%,.2f" (- (+ (reduce + 0.0 (map :sales-summary-item/total (:sales-summary/sales-items ss)))
(reduce + 0.0 (map :sales-summary-item/discount (:sales-summary/sales-items ss))))
(reduce + 0.0 (map :sales-summary-item/tax (:sales-summary/sales-items ss)))))]
[:li "Tax: " (format "$%,.2f" (:sales-summary/total-tax ss))]
[:li "Tips: " (format "$%,.2f" (:sales-summary/total-tip ss))]
(for [si (:sales-summary/sales-items ss)
:when (= :ledger-side/credit (:ledger-mapped/ledger-side si))]
[:li (:sales-summary-item/category si) ": " (format "$%,.2f" (:ledger-mapped/amount si))])
[:li "Sales subtotal: " (format "$%,.2f" (reduce + 0.0 (map :ledger-mapped/amount (:sales-summary/sales-items ss))))]
(for [si (:sales-summary/payment-items ss)
:when (= :ledger-side/credit (:ledger-mapped/ledger-side si))]
[:li (:sales-summary-item/category si) ": " (format "$%,.2f" (:ledger-mapped/amount si))])
[:li "Tax: " (format "$%,.2f" (:ledger-mapped/amount (:sales-summary/total-tax ss)))]
[:li "Tips: " (format "$%,.2f" (:ledger-mapped/amount (:sales-summary/total-tip ss)))]
[:li (com/pill {:color (if (dollars= total-debits total-credits)
:primary
:red)} "Total: " (format "$%,.2f" total-credits))]])
@@ -188,51 +204,22 @@
:name "debits"
:sort-key "debits"
:render (fn [ss]
(let [{:keys [card-payments food-app-payments
cash-payments discounts fees
gift-card-payments
returns refunds total-unknown-processor-payments] :as debits} (get-debits ss)
total-debits (reduce + 0.0 (vals debits))
total-credits (+ (- (+ (reduce + 0.0 (map :sales-summary-item/total (:sales-summary/sales-items ss)))
(reduce + 0.0 (map :sales-summary-item/discount (:sales-summary/sales-items ss))))
(reduce + 0.0 (map :sales-summary-item/tax (:sales-summary/sales-items ss))))
(:sales-summary/total-tax ss 0.0)
(:sales-summary/total-tip ss 0.0))]
(let [ total-debits (->> (all-items ss)
(filter #(= :ledger-side/debit (:ledger-mapped/ledger-side %)))
(map #(:ledger-mapped/amount % 0.0))
(reduce + 0.0))
total-credits (->> (all-items ss)
(filter #(= :ledger-side/credit (:ledger-mapped/ledger-side %)))
(map #(:ledger-mapped/amount % 0.0))
(reduce + 0.0))]
[:ul
[:li "Card Payments: "
(format "$%,.2f" card-payments)]
[:li "Food App Payments: "
(format "$%,.2f" food-app-payments)]
[:li "Gift Card Payments"
(format "$%,.2f" gift-card-payments)]
[:li "Unknown Processor Payments: "
(format "$%,.2f" total-unknown-processor-payments)]
[:li "Cash Payments: "
(format "$%,.2f" cash-payments)]
[:li "Discounts: "
(format "$%,.2f" discounts)]
[:li "Fees: "
(format "$%,.2f" fees)]
[:li "Returns: "
(format "$%,.2f" returns)]
#_[:li "Refunds: "
(format "$%,.2f" refunds)]
(for [si (:sales-summary/payment-items ss)
:when (= :ledger-side/debit (:ledger-mapped/ledger-side si))]
[:li (:sales-summary-item/category si) ": " (format "$%,.2f" (:ledger-mapped/amount si))])
[:li (com/pill {:color (if (dollars= total-debits total-credits)
:primary
:red)} "Total: " (format "$%,.2f" total-debits))]])
#_(count))}]}))
;; TODO schema cleanup