From af66049f39092ff7901329d458a089635ae54262 Mon Sep 17 00:00:00 2001 From: Bryce Date: Fri, 1 May 2026 14:05:23 -0700 Subject: [PATCH] consolidate sales summary ledger entry creation into upsert-sales-summary tx Move journal entry calculation and creation from the reconcile-ledger background job into the upsert-sales-summary tx function. Now any save of a sales summary (job recalculation, admin edit wizard, or manual touch) automatically creates the journal entry if balanced with all accounts mapped, or retracts it if conditions no longer hold. Eliminates the need for a separate upsert-sales-summary-ledger call and the reconcile ledger pass for sales summaries. --- iol_ion/src/iol_ion/tx.clj | 2 +- .../tx/upsert_sales_summary_ledger.clj | 78 +++++++------------ src/clj/auto_ap/jobs/sales_summaries.clj | 36 +-------- src/clj/auto_ap/ledger.clj | 2 +- src/clj/auto_ap/ssr/admin/sales_summaries.clj | 2 +- 5 files changed, 34 insertions(+), 86 deletions(-) diff --git a/iol_ion/src/iol_ion/tx.clj b/iol_ion/src/iol_ion/tx.clj index 79f0bf7c..69f7fbb3 100644 --- a/iol_ion/src/iol_ion/tx.clj +++ b/iol_ion/src/iol_ion/tx.clj @@ -50,7 +50,7 @@ (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-sales-summary-ledger #'iol-ion.tx.upsert-sales-summary-ledger/upsert-sales-summary-ledger)]))) + (datomic-fn :upsert-sales-summary #'iol-ion.tx.upsert-sales-summary-ledger/upsert-sales-summary)]))) (comment (regenerate-literals) diff --git a/iol_ion/src/iol_ion/tx/upsert_sales_summary_ledger.clj b/iol_ion/src/iol_ion/tx/upsert_sales_summary_ledger.clj index 8fb30e2c..26db4a9f 100644 --- a/iol_ion/src/iol_ion/tx/upsert_sales_summary_ledger.clj +++ b/iol_ion/src/iol_ion/tx/upsert_sales_summary_ledger.clj @@ -1,28 +1,7 @@ (ns iol-ion.tx.upsert-sales-summary-ledger - (:import [java.util UUID Date]) - (:require [datomic.api :as dc])) - -(defn -random-tempid [] - (dc/tempid :db.part/user)) - -(def extant-read '[:db/id :journal-entry/date :journal-entry/client {:journal-entry/line-items [:journal-entry-line/account :journal-entry-line/location :db/id :journal-entry-line/client+account+location+date]}]) - -(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 calc-client+account+location+date [je jel] - [(or - (:db/id (:journal-entry/client je)) - (:journal-entry/client je)) - (or (:db/id (:journal-entry-line/account jel)) - (:journal-entry-line/account jel)) - (-> jel :journal-entry-line/location) - (-> je :journal-entry/date)]) + (:require [datomic.api :as dc] + [iol-ion.tx.upsert-entity :as upsert-entity] + [iol-ion.tx.upsert-ledger :as upsert-ledger])) (defn summary->journal-entry [db summary-id] (let [summary (dc/pull db '[:sales-summary/client @@ -42,37 +21,40 @@ (update m (:ledger-mapped/ledger-side item) (fnil + 0.0) (:ledger-mapped/amount item 0.0))) {:account account} acc-items)))) - line-items (mapv (fn [{:keys [account] :as m}] - (cond-> {:db/id (str (java.util.UUID/randomUUID)) - :journal-entry-line/account account} + 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-amount (reduce + 0.0 (map #(get % :ledger-side/debit 0.0) aggregated))] - (when (seq line-items) + 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))] + (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-amount + :journal-entry/amount total-debits :journal-entry/line-items line-items}))) -(defn upsert-sales-summary-ledger [db summary] - (assert (:db/id summary) "Must provide summary id") - (let [upserted-entity [[:upsert-entity {:db/id (:db/id summary)}]] - with-summary (dc/with db upserted-entity) - summary-id (:db/id summary) - journal-entry (summary->journal-entry (:db-after with-summary) summary-id) - client-id (-> (dc/pull (:db-after with-summary) - [{:sales-summary/client [:db/id]}] - summary-id) +(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)] - (into upserted-entity + :db/id) + journal-entry (summary->journal-entry db-after summary-id)] + (into upserted-summary (if journal-entry - [[:upsert-ledger journal-entry] - {:db/id client-id - :client/ledger-last-change (current-date db)}] - [[:db/retractEntity [:journal-entry/original-entity summary-id]] - {:db/id client-id - :client/ledger-last-change (current-date db)}])))) + [[:upsert-ledger journal-entry]] + (let [existing-je-id (ffirst (dc/q '[:find ?je . :in $ ?ss + :where [?je :journal-entry/original-entity ?ss]] + db-after summary-id))] + (concat + (when existing-je-id [[:db/retractEntity existing-je-id]]) + (when client-id [{:db/id client-id + :client/ledger-last-change (upsert-ledger/current-date db)}]))))))) diff --git a/src/clj/auto_ap/jobs/sales_summaries.clj b/src/clj/auto_ap/jobs/sales_summaries.clj index 1a81a222..9f1b02b7 100644 --- a/src/clj/auto_ap/jobs/sales_summaries.clj +++ b/src/clj/auto_ap/jobs/sales_summaries.clj @@ -276,40 +276,6 @@ :ledger-mapped/amount amount :ledger-mapped/ledger-side :ledger-side/debit})) -(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]}] - summary-id) - items (:sales-summary/items summary) - ;; Aggregate items by account and ledger side - aggregated (->> items - (filter :ledger-mapped/account) - (group-by :ledger-mapped/account) - (map (fn [[account acc-items]] - (reduce - (fn [m item] - (update m (:ledger-mapped/ledger-side item) (fnil + 0.0) (:ledger-mapped/amount item 0.0))) - {:account account} - acc-items)))) - line-items (mapv (fn [{:keys [account] :as m}] - (cond-> {:db/id (str (java.util.UUID/randomUUID)) - :journal-entry-line/account account} - (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-amount (reduce + 0.0 (map #(get % :ledger-side/debit 0.0) aggregated))] - (when (seq line-items) - {: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-amount - :journal-entry/line-items line-items}))) - (defn- calc-aggregate-totals [items] (reduce (fn [acc item] @@ -376,7 +342,7 @@ (do (alog/info ::upserting-summaries :category-count (count (:sales-summary/items result))) - @(dc/transact conn [[:upsert-entity result]])) + @(dc/transact conn [[:upsert-sales-summary result]])) @(dc/transact conn [{:db/id id :sales-summary/dirty false}])))))) diff --git a/src/clj/auto_ap/ledger.clj b/src/clj/auto_ap/ledger.clj index 19a71609..2f6a1f4a 100644 --- a/src/clj/auto_ap/ledger.clj +++ b/src/clj/auto_ap/ledger.clj @@ -61,7 +61,7 @@ (dc/db conn) start-date) (map first) (mapv (fn [ss] - [:upsert-sales-summary-ledger {:db/id ss}]))) + [:upsert-sales-summary {:db/id ss}]))) repairs (vec (concat txes-missing-ledger-entries invoices-missing-ledger-entries sales-summaries-missing-ledger-entries))] (when (seq repairs) diff --git a/src/clj/auto_ap/ssr/admin/sales_summaries.clj b/src/clj/auto_ap/ssr/admin/sales_summaries.clj index 80e0e975..144ab20e 100644 --- a/src/clj/auto_ap/ssr/admin/sales_summaries.clj +++ b/src/clj/auto_ap/ssr/admin/sales_summaries.clj @@ -483,7 +483,7 @@ edit-schema) (submit [this {:keys [multi-form-state request-method identity] :as request}] (let [result (:snapshot multi-form-state ) - transaction [:upsert-entity {:db/id (:db/id result) + transaction [:upsert-sales-summary {:db/id (:db/id result) :sales-summary/items (map (fn [i] (if (:sales-summary-item/manual? i)