Feat/Complete Sales Summaries (#5)
## Summary Completes the automatic sales summary pipeline end-to-end: the `sales-summaries-v2` job now calculates aggregate totals, preserves manual adjustments, and automatically posts balanced journal entries to the ledger. ## What Changed **New Datomic transaction function** (`upsert-sales-summary-ledger`) - Transforms detailed `sales-summary-item`s into aggregated `journal-entry` lines grouped by account and ledger side - Handles the full upsert: posts a new journal entry for summaries with mapped accounts, or retracts the orphaned entry if items no longer qualify **Enhanced `sales-summaries-v2` job** - Calculates and stores 13 aggregate total attributes (card/cash/food-app/gift-card payments, refunds, fees, discounts, tax, tip, returns, unknown, net) - Preserves manual items (`manual? true`) during recalculation — only auto-calculated items are replaced **Ledger reconciliation** - `reconcile-ledger` now queries for sales summaries missing journal entries and repairs them via `:upsert-sales-summary-ledger`, alongside existing invoice and transaction repairs **Schema** - Added 13 `total-*` attributes on `sales-summary` (all `db.type/double`, no history) - Registered the new transaction function in `tx.clj` and `datomic.clj` **Admin UI cleanup** - Resolved "clientize" and HTMX `client-id` TODOs in the sales summaries admin page - `new-summary-item` now correctly passes `client-id` via `hx-vals` - Removed stale TODO comments and placeholder code ## Files Changed (8) | File | Purpose | |------|---------| | `iol_ion/.../upsert_sales_summary_ledger.clj` | New Datomic tx function | | `iol_ion/.../tx.clj` | Register new tx function | | `resources/schema.edn` | 13 new `total-*` attributes | | `src/.../datomic.clj` | Load new tx namespace | | `src/.../jobs/sales_summaries.clj` | Aggregate totals + manual item preservation | | `src/.../ledger.clj` | Sales summary repair in `reconcile-ledger` | | `src/.../ssr/admin/sales_summaries.clj` | UI TODO cleanup | | `docs/plans/...plan.md` | Implementation plan document | Co-authored-by: Bryce <bryce@integreatconsult.com> Reviewed-on: #5 Co-authored-by: Bryce <bryce@brycecovertoperations.com> Co-committed-by: Bryce <bryce@brycecovertoperations.com>
This commit was merged in pull request #5.
This commit is contained in:
@@ -49,9 +49,9 @@
|
||||
(datomic-fn :upsert-entity #'iol-ion.tx.upsert-entity/upsert-entity)
|
||||
(datomic-fn :upsert-invoice #'iol-ion.tx.upsert-invoice/upsert-invoice)
|
||||
(datomic-fn :upsert-ledger #'iol-ion.tx.upsert-ledger/upsert-ledger)
|
||||
(datomic-fn :upsert-transaction #'iol-ion.tx.upsert-transaction/upsert-transaction)])))
|
||||
(datomic-fn :upsert-transaction #'iol-ion.tx.upsert-transaction/upsert-transaction)
|
||||
(datomic-fn :upsert-sales-summary #'iol-ion.tx.upsert-sales-summary-ledger/upsert-sales-summary)])))
|
||||
|
||||
(comment
|
||||
(regenerate-literals)
|
||||
|
||||
(auto-ap.datomic/install-functions))
|
||||
(auto-ap.datomic/install-functions))
|
||||
|
||||
70
iol_ion/src/iol_ion/tx/upsert_sales_summary_ledger.clj
Normal file
70
iol_ion/src/iol_ion/tx/upsert_sales_summary_ledger.clj
Normal file
@@ -0,0 +1,70 @@
|
||||
(ns iol-ion.tx.upsert-sales-summary-ledger
|
||||
(:require [datomic.api :as dc]))
|
||||
|
||||
(defn summary->journal-entry [db summary-id]
|
||||
(let [summary (dc/pull db '[:sales-summary/client
|
||||
:sales-summary/date
|
||||
{:sales-summary/items [:sales-summary-item/category
|
||||
:ledger-mapped/account
|
||||
:ledger-mapped/amount
|
||||
{:ledger-mapped/ledger-side [:db/ident]}]}]
|
||||
summary-id)
|
||||
items (:sales-summary/items summary)
|
||||
aggregated (->> items
|
||||
(filter :ledger-mapped/account)
|
||||
(group-by :ledger-mapped/account)
|
||||
(map (fn [[account acc-items]]
|
||||
(reduce
|
||||
(fn [m item]
|
||||
(update m (:db/ident (:ledger-mapped/ledger-side item)) (fnil + 0.0) (:ledger-mapped/amount item 0.0)))
|
||||
{:account account}
|
||||
acc-items))))
|
||||
_ (clojure.pprint/pprint aggregated)
|
||||
line-items (mapv (fn [{:keys [account] :as m}]
|
||||
(cond-> {:db/id (str (java.util.UUID/randomUUID))
|
||||
:journal-entry-line/account account
|
||||
:journal-entry-line/location "A"}
|
||||
(get m :ledger-side/debit) (assoc :journal-entry-line/debit (get m :ledger-side/debit))
|
||||
(get m :ledger-side/credit) (assoc :journal-entry-line/credit (get m :ledger-side/credit))))
|
||||
aggregated)
|
||||
|
||||
total-debits (reduce + 0.0 (map #(get % :ledger-side/debit 0.0) aggregated))
|
||||
total-credits (reduce + 0.0 (map #(get % :ledger-side/credit 0.0) aggregated))
|
||||
_ (clojure.pprint/pprint [total-debits total-credits])
|
||||
]
|
||||
(when (and (seq line-items)
|
||||
(= (Math/round (* 1000 total-debits))
|
||||
(Math/round (* 1000 total-credits))))
|
||||
{:journal-entry/source "sales-summary"
|
||||
:journal-entry/client (:db/id (:sales-summary/client summary))
|
||||
:journal-entry/date (:sales-summary/date summary)
|
||||
:journal-entry/original-entity summary-id
|
||||
:journal-entry/amount total-debits
|
||||
:journal-entry/line-items line-items})))
|
||||
|
||||
(defn current-date [db]
|
||||
(let [last-tx (dc/t->tx (dc/basis-t db))
|
||||
[[date]] (seq (dc/q '[:find ?ti :in $ ?tx
|
||||
:where [?tx :db/txInstant ?ti]]
|
||||
db
|
||||
last-tx))]
|
||||
date))
|
||||
|
||||
(defn upsert-sales-summary [db summary]
|
||||
(let [upserted-summary [[:upsert-entity summary]]
|
||||
db-after (-> (dc/with db upserted-summary) :db-after)
|
||||
summary-id (:db/id summary)
|
||||
client-id (-> (dc/pull db-after [{:sales-summary/client [:db/id]}] summary-id)
|
||||
:sales-summary/client
|
||||
:db/id)
|
||||
journal-entry (summary->journal-entry db-after summary-id)]
|
||||
upserted-summary
|
||||
#_(into upserted-summary
|
||||
(if journal-entry
|
||||
[[:upsert-ledger journal-entry]]
|
||||
(concat
|
||||
[[:db/retractEntity [:journal-entry/original-entity (:db/id summary)]]]
|
||||
|
||||
|
||||
(when client-id [{:db/id client-id
|
||||
:client/ledger-last-change (current-date db)}]))))))
|
||||
Reference in New Issue
Block a user