Feat/Complete Sales Summaries #5
@@ -50,7 +50,7 @@
|
|||||||
(datomic-fn :upsert-invoice #'iol-ion.tx.upsert-invoice/upsert-invoice)
|
(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-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-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
|
(comment
|
||||||
(regenerate-literals)
|
(regenerate-literals)
|
||||||
|
|||||||
@@ -1,28 +1,7 @@
|
|||||||
(ns iol-ion.tx.upsert-sales-summary-ledger
|
(ns iol-ion.tx.upsert-sales-summary-ledger
|
||||||
(:import [java.util UUID Date])
|
(:require [datomic.api :as dc]
|
||||||
(:require [datomic.api :as dc]))
|
[iol-ion.tx.upsert-entity :as upsert-entity]
|
||||||
|
[iol-ion.tx.upsert-ledger :as upsert-ledger]))
|
||||||
(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)])
|
|
||||||
|
|
||||||
(defn summary->journal-entry [db summary-id]
|
(defn summary->journal-entry [db summary-id]
|
||||||
(let [summary (dc/pull db '[:sales-summary/client
|
(let [summary (dc/pull db '[:sales-summary/client
|
||||||
@@ -44,35 +23,38 @@
|
|||||||
acc-items))))
|
acc-items))))
|
||||||
line-items (mapv (fn [{:keys [account] :as m}]
|
line-items (mapv (fn [{:keys [account] :as m}]
|
||||||
(cond-> {:db/id (str (java.util.UUID/randomUUID))
|
(cond-> {:db/id (str (java.util.UUID/randomUUID))
|
||||||
:journal-entry-line/account account}
|
: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/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))))
|
(get m :ledger-side/credit) (assoc :journal-entry-line/credit (get m :ledger-side/credit))))
|
||||||
aggregated)
|
aggregated)
|
||||||
total-amount (reduce + 0.0 (map #(get % :ledger-side/debit 0.0) aggregated))]
|
total-debits (reduce + 0.0 (map #(get % :ledger-side/debit 0.0) aggregated))
|
||||||
(when (seq line-items)
|
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/source "sales-summary"
|
||||||
:journal-entry/client (:db/id (:sales-summary/client summary))
|
:journal-entry/client (:db/id (:sales-summary/client summary))
|
||||||
:journal-entry/date (:sales-summary/date summary)
|
:journal-entry/date (:sales-summary/date summary)
|
||||||
:journal-entry/original-entity summary-id
|
:journal-entry/original-entity summary-id
|
||||||
:journal-entry/amount total-amount
|
:journal-entry/amount total-debits
|
||||||
:journal-entry/line-items line-items})))
|
:journal-entry/line-items line-items})))
|
||||||
|
|
||||||
(defn upsert-sales-summary-ledger [db summary]
|
(defn upsert-sales-summary [db summary]
|
||||||
(assert (:db/id summary) "Must provide summary id")
|
(let [upserted-summary [[:upsert-entity summary]]
|
||||||
(let [upserted-entity [[:upsert-entity {:db/id (:db/id summary)}]]
|
db-after (-> (dc/with db upserted-summary) :db-after)
|
||||||
with-summary (dc/with db upserted-entity)
|
|
||||||
summary-id (:db/id summary)
|
summary-id (:db/id summary)
|
||||||
journal-entry (summary->journal-entry (:db-after with-summary) summary-id)
|
client-id (-> (dc/pull db-after [{:sales-summary/client [:db/id]}] summary-id)
|
||||||
client-id (-> (dc/pull (:db-after with-summary)
|
|
||||||
[{:sales-summary/client [:db/id]}]
|
|
||||||
summary-id)
|
|
||||||
:sales-summary/client
|
:sales-summary/client
|
||||||
:db/id)]
|
:db/id)
|
||||||
(into upserted-entity
|
journal-entry (summary->journal-entry db-after summary-id)]
|
||||||
|
(into upserted-summary
|
||||||
(if journal-entry
|
(if journal-entry
|
||||||
[[:upsert-ledger journal-entry]
|
[[:upsert-ledger journal-entry]]
|
||||||
{:db/id client-id
|
(let [existing-je-id (ffirst (dc/q '[:find ?je . :in $ ?ss
|
||||||
:client/ledger-last-change (current-date db)}]
|
:where [?je :journal-entry/original-entity ?ss]]
|
||||||
[[:db/retractEntity [:journal-entry/original-entity summary-id]]
|
db-after summary-id))]
|
||||||
{:db/id client-id
|
(concat
|
||||||
:client/ledger-last-change (current-date db)}]))))
|
(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)}])))))))
|
||||||
|
|||||||
@@ -276,40 +276,6 @@
|
|||||||
:ledger-mapped/amount amount
|
:ledger-mapped/amount amount
|
||||||
:ledger-mapped/ledger-side :ledger-side/debit}))
|
: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]
|
(defn- calc-aggregate-totals [items]
|
||||||
(reduce
|
(reduce
|
||||||
(fn [acc item]
|
(fn [acc item]
|
||||||
@@ -376,7 +342,7 @@
|
|||||||
(do
|
(do
|
||||||
(alog/info ::upserting-summaries
|
(alog/info ::upserting-summaries
|
||||||
:category-count (count (:sales-summary/items result)))
|
: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}]))))))
|
@(dc/transact conn [{:db/id id :sales-summary/dirty false}]))))))
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -61,7 +61,7 @@
|
|||||||
(dc/db conn) start-date)
|
(dc/db conn) start-date)
|
||||||
(map first)
|
(map first)
|
||||||
(mapv (fn [ss]
|
(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))]
|
repairs (vec (concat txes-missing-ledger-entries invoices-missing-ledger-entries sales-summaries-missing-ledger-entries))]
|
||||||
(when (seq repairs)
|
(when (seq repairs)
|
||||||
|
|||||||
@@ -483,7 +483,7 @@
|
|||||||
edit-schema)
|
edit-schema)
|
||||||
(submit [this {:keys [multi-form-state request-method identity] :as request}]
|
(submit [this {:keys [multi-form-state request-method identity] :as request}]
|
||||||
(let [result (:snapshot multi-form-state )
|
(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
|
:sales-summary/items (map
|
||||||
(fn [i]
|
(fn [i]
|
||||||
(if (:sales-summary-item/manual? i)
|
(if (:sales-summary-item/manual? i)
|
||||||
|
|||||||
Reference in New Issue
Block a user