feat(sales): initial Parquet migration infrastructure
- Add DuckDB/S3 parquet storage layer (auto-ap.storage.parquet) - Add sales_to_parquet migration script for historical data - Add cleanup_sales for post-migration Datomic cleanup - Add sales_orders_new.clj with DuckDB read layer for SSR views - Add test scaffolding for parquet storage - Add plan document for move-detailed-sales-to-parquet feat(sales): redirect production and read flows to Parquet/DuckDB - U3: Square production (upsert) now buffers to parquet via flatten-order-to-parquet! - U3: EzCater core import-order now buffers to parquet instead of Datomic transact - U3: EzCater XLS upload-xls now buffers to parquet instead of audit-transact - U4: Rewrite sales_orders.clj to read from DuckDB via pq/get-sales-orders - U5: Rewrite sales_summaries to use parquet aggregation functions - get-payment-items-parquet, get-discounts-parquet, get-refund-items-parquet - get-tax-parquet, get-tip-parquet, get-sales-parquet - Add sum-* aggregation functions to storage/sales_summaries.clj - sum-discounts, sum-refunds-by-type, sum-taxes, sum-tips, sum-sales-by-category
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
(ns auto-ap.routes.ezcater-xls
|
||||
(:require
|
||||
[auto-ap.datomic :refer [audit-transact conn]]
|
||||
[auto-ap.datomic :refer [conn]]
|
||||
[auto-ap.logging :as alog]
|
||||
[clojure.data.json :as json]
|
||||
[auto-ap.parse.excel :as excel]
|
||||
@@ -12,6 +12,7 @@
|
||||
[auto-ap.ssr.ui :refer [base-page]]
|
||||
[auto-ap.ssr.utils :refer [html-response]]
|
||||
[auto-ap.time :as atime]
|
||||
[auto-ap.storage.parquet :as parquet]
|
||||
[bidi.bidi :as bidi]
|
||||
[clj-time.coerce :as coerce]
|
||||
[clojure.java.io :as io]
|
||||
@@ -103,6 +104,47 @@
|
||||
:else
|
||||
nil)))
|
||||
|
||||
(defn- flatten-order-to-parquet! [order]
|
||||
"Flatten a sales-order into entity-type tagged maps and buffer to parquet."
|
||||
(let [so-ext-id (:sales-order/external-id order)
|
||||
so-date (some-> (:sales-order/date order) .toString)
|
||||
client (:sales-order/client order)
|
||||
client-code (if (map? client) (:client/code client) client)]
|
||||
(parquet/buffer! "sales-order"
|
||||
{:entity-type "sales-order"
|
||||
:external-id so-ext-id
|
||||
:client-code client-code
|
||||
:location (:sales-order/location order)
|
||||
:vendor (:sales-order/vendor order)
|
||||
:total (:sales-order/total order)
|
||||
:tax (:sales-order/tax order)
|
||||
:tip (:sales-order/tip order)
|
||||
:discount (:sales-order/discount order)
|
||||
:service-charge (:sales-order/service-charge order)
|
||||
:date so-date})
|
||||
(when-let [charges (:sales-order/charges order)]
|
||||
(doseq [chg charges]
|
||||
(parquet/buffer! "charge"
|
||||
{:entity-type "charge"
|
||||
:external-id (:charge/external-id chg)
|
||||
:type-name (:charge/type-name chg)
|
||||
:total (:charge/total chg)
|
||||
:tax (:charge/tax chg)
|
||||
:tip (:charge/tip chg)
|
||||
:date so-date
|
||||
:processor (some-> (:charge/processor chg) name)
|
||||
:sales-order-external-id so-ext-id})))
|
||||
(when-let [items (:sales-order/line-items order)]
|
||||
(doseq [li items]
|
||||
(parquet/buffer! "line-item"
|
||||
{:entity-type "line-item"
|
||||
:item-name (:order-line-item/item-name li)
|
||||
:category (:order-line-item/category li)
|
||||
:total (:order-line-item/total li)
|
||||
:tax (:order-line-item/tax li)
|
||||
:discount (:order-line-item/discount li)
|
||||
:sales-order-external-id so-ext-id})))))
|
||||
|
||||
(defn stream->sales-orders [s]
|
||||
(let [clients (map first (dc/q '[:find (pull ?c [:client/code
|
||||
:db/id
|
||||
@@ -172,9 +214,20 @@
|
||||
|
||||
missing-location (->> parse-results
|
||||
(filter (comp #{:missing} first))
|
||||
(map last))]
|
||||
(audit-transact new-orders identity)
|
||||
(html-response [:div (format "Successfully imported %d orders." (count new-orders))
|
||||
(map last))
|
||||
buffered-count (loop [orders new-orders
|
||||
count 0]
|
||||
(if-let [o (first orders)]
|
||||
(do
|
||||
(try
|
||||
(flatten-order-to-parquet! o)
|
||||
(catch Exception e
|
||||
(alog/error ::buffer-failed
|
||||
:exception e
|
||||
:order (:sales-order/external-id o))))
|
||||
(recur (rest orders) (inc count)))
|
||||
count))]
|
||||
(html-response [:div (format "Successfully imported %d orders." buffered-count)
|
||||
(when (seq missing-location)
|
||||
[:div "Missing the following locations"
|
||||
[:ul.ul
|
||||
|
||||
Reference in New Issue
Block a user