Allows users to self set up square
This commit is contained in:
@@ -7,7 +7,6 @@
|
||||
[clj-time.core :as time]
|
||||
[clj-time.periodic :as periodic]
|
||||
[clj-time.format :as f]
|
||||
[config.core :refer [env] :as cfg ]
|
||||
[clojure.string :as str]
|
||||
[clojure.data.json :as json]
|
||||
[clojure.tools.logging :as log]
|
||||
@@ -17,10 +16,14 @@
|
||||
[yang.scheduler :as scheduler]
|
||||
[clojure.core.async :as async]))
|
||||
|
||||
(defn base-headers [client]
|
||||
(defn client-base-headers [client]
|
||||
{"Square-Version" "2021-08-18"
|
||||
"Authorization" (str "Bearer " (get-in env [:square-config client :token]))
|
||||
"Content-Type" "application/json"})
|
||||
"Authorization" (str "Bearer " (:client/square-auth-token client))
|
||||
"Content-Type" "application/json"})
|
||||
|
||||
(defn retry-4 [ex try-count _]
|
||||
(log/warn "Retrying after failure " ex)
|
||||
(if (> try-count 4) false true))
|
||||
|
||||
(defn lookup-dates []
|
||||
(->> (periodic/periodic-seq (time/plus (time/now) (time/days -15))
|
||||
@@ -38,12 +41,23 @@
|
||||
:body
|
||||
:locations))
|
||||
|
||||
(defn client-locations [client]
|
||||
(try
|
||||
(->> (client/get "https://connect.squareup.com/v2/locations"
|
||||
{:headers (client-base-headers client)
|
||||
:as :json})
|
||||
:body
|
||||
:locations)
|
||||
(catch Exception e
|
||||
(log/warn e)
|
||||
[])))
|
||||
|
||||
(defn fetch-catalog [client i]
|
||||
(if i
|
||||
(try
|
||||
(log/info "looking up catalog for" (str "https://connect.squareup.com/v2/catalog/object/" i))
|
||||
(->> (client/get (str "https://connect.squareup.com/v2/catalog/object/" i)
|
||||
{:headers (base-headers client)
|
||||
{:headers (client-base-headers client)
|
||||
:query-params {"include_related_items" "true"}
|
||||
:as :json})
|
||||
:body
|
||||
@@ -71,28 +85,6 @@
|
||||
(log/warn "couldn't look up" i)
|
||||
"Uncategorized"))))
|
||||
|
||||
(defn categories []
|
||||
(by :id (comp :name :category_data) ))
|
||||
|
||||
(def potential-query
|
||||
{"query" {"filter" {"date_time_filter"
|
||||
{
|
||||
"created_at" {
|
||||
"start_at" "2020-08-28T00:00:00-07:00",
|
||||
"end_at" "2020-08-28T23:59:59-07:00"
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
"state_filter" {"states" ["COMPLETED"]}}
|
||||
|
||||
"sort" {
|
||||
"sort_field" "CREATED_AT"
|
||||
"sort_order" "DESC"
|
||||
}}})
|
||||
|
||||
|
||||
(defn pc [d] {"query" {"filter" {"date_time_filter"
|
||||
{
|
||||
"created_at" {
|
||||
@@ -111,17 +103,14 @@
|
||||
|
||||
|
||||
(defn search
|
||||
([client]
|
||||
(search client (get-in env [:square-config client :square-location])))
|
||||
([client l]
|
||||
(search client l nil))
|
||||
([client l d]
|
||||
(log/info "Searching for" l)
|
||||
([client location d]
|
||||
(log/info "Searching for" (:square-location/client-location location))
|
||||
(let [result (->> (client/post "https://connect.squareup.com/v2/orders/search"
|
||||
{:headers (base-headers client)
|
||||
:body (json/write-str (cond-> {"location_ids" [l] "limit" 10000}
|
||||
d (merge (pc d))))
|
||||
:as :json})
|
||||
(doto {:headers (client-base-headers client)
|
||||
:body (json/write-str (cond-> {"location_ids" [(:square-location/square-id location)] "limit" 10000}
|
||||
d (merge (pc d))))
|
||||
:as :json}
|
||||
clojure.pprint/pprint))
|
||||
:body
|
||||
:orders)]
|
||||
(log/info "found " (count result))
|
||||
@@ -143,8 +132,6 @@
|
||||
(defn amount->money [amt]
|
||||
(* 0.01 (or (:amount amt) 0.0)))
|
||||
|
||||
(defn location_id->client-location [location]
|
||||
(get-in env [:square-location location]))
|
||||
|
||||
;; to get totals:
|
||||
(comment
|
||||
@@ -164,9 +151,9 @@
|
||||
(remove-nils
|
||||
#:sales-order
|
||||
{:date (coerce/to-date (time/to-time-zone (coerce/to-date-time (:created_at order)) (time/time-zone-for-id "America/Los_Angeles")))
|
||||
:client [:client/code client]
|
||||
:location location
|
||||
:external-id (str "square/order/" client "-" location "-" (:id order))
|
||||
:client (:db/id client)
|
||||
:location (:square-location/client-location location)
|
||||
:external-id (str "square/order/" (:client/code client) "-" (:square-location/client-location location) "-" (:id order))
|
||||
:vendor :vendor/ccp-square
|
||||
:total (-> order :net_amounts :total_money amount->money)
|
||||
:tax (-> order :net_amounts :tax_money amount->money)
|
||||
@@ -211,10 +198,8 @@
|
||||
:discount (amount->money (:total_discount_money li))}))))}))
|
||||
|
||||
(defn daily-results
|
||||
([client]
|
||||
(daily-results client nil))
|
||||
([client d]
|
||||
(daily-results client (get-in env [:square-config client :square-location]) d))
|
||||
([client location]
|
||||
(daily-results client location nil))
|
||||
([client location d]
|
||||
(->> (search client location d)
|
||||
(filter (fn [order]
|
||||
@@ -228,7 +213,7 @@
|
||||
(and
|
||||
(not= "Koala" (:name (:source order)))
|
||||
(not= "koala-production" (:name (:source order))))))
|
||||
(map #(order->sales-order client (get-in env [:square-config client :location]) %)))))
|
||||
(map #(order->sales-order client location %)))))
|
||||
|
||||
#_(daily-results)
|
||||
|
||||
@@ -246,11 +231,9 @@
|
||||
|
||||
(defn get-payment [client p]
|
||||
(:payment (:body (retry #(client/get (str "https://connect.squareup.com/v2/payments/" p)
|
||||
{:headers (base-headers client)
|
||||
{:headers (client-base-headers client)
|
||||
:as :json
|
||||
:retry-handler (fn [ex try-count http-context]
|
||||
(log/warn "Retrying after failure " ex)
|
||||
(if (> try-count 4) false true))})))))
|
||||
:retry-handler retry-4})))))
|
||||
|
||||
(defn get-settlement-sales-date [client settlement]
|
||||
(let [concurrent 10
|
||||
@@ -282,24 +265,23 @@
|
||||
(drop 2)
|
||||
first)))
|
||||
|
||||
(defn get-settlement-details [client settlements] ;; pairs of [location settlement]
|
||||
(defn get-settlement-details [client location settlements] ;; pairs of [location settlement]
|
||||
(log/info "getting settlement details for " settlements)
|
||||
(let [concurrent 10
|
||||
output-chan (async/chan)]
|
||||
(async/pipeline-blocking concurrent
|
||||
output-chan
|
||||
(map (fn [[location s :as g]]
|
||||
(map (fn [s]
|
||||
(lc/with-context {:source "Square settlements loading "}
|
||||
(log/info "Looking up settlement " s " for location " location)
|
||||
(let [settlement (:body (retry #(client/get (str "https://connect.squareup.com/v1/" location "/settlements/" s)
|
||||
{:headers (base-headers client)
|
||||
(log/info "Looking up settlement " s " for location " (:square-location/client-location location))
|
||||
(let [settlement (:body (retry #(client/get (str "https://connect.squareup.com/v1/" (:square-location/square-id location) "/settlements/" s)
|
||||
{:headers (client-base-headers client)
|
||||
:as :json
|
||||
:retry-handler (fn [ex try-count http-context]
|
||||
(log/warn "Retrying after failure " ex)
|
||||
(if (> try-count 4) false true))})))]
|
||||
:retry-handler retry-4})))
|
||||
sales-date (get-settlement-sales-date client settlement)]
|
||||
|
||||
(log/info "sales date for " s " is " (get-settlement-sales-date client settlement))
|
||||
(assoc settlement :sales-date (get-settlement-sales-date client settlement) )))))
|
||||
(log/info "sales date for " s " is " sales-date)
|
||||
(assoc settlement :sales-date sales-date)))))
|
||||
(async/to-chan settlements)
|
||||
true
|
||||
(fn [e]
|
||||
@@ -308,14 +290,14 @@
|
||||
(async/<!! (async/into [] output-chan))))
|
||||
|
||||
(defn settlements
|
||||
([client l] (settlements client l (lookup-dates)))
|
||||
([client l lookup-dates]
|
||||
(log/info "Searching for" l)
|
||||
([client location] (settlements client location (lookup-dates)))
|
||||
([client location lookup-dates]
|
||||
(log/info "Searching for" (:square-location/client-location location))
|
||||
(->> lookup-dates
|
||||
(mapcat (fn [[start-date end-date]]
|
||||
(log/info "looking up settlements for " l " on dates " start-date " to " end-date)
|
||||
(let [settlements (->> (client/get (str "https://connect.squareup.com/v1/" l "/settlements")
|
||||
{:headers (base-headers client)
|
||||
(log/info "looking up settlements for " (:square-location/client-location location) " on dates " start-date " to " end-date)
|
||||
(let [settlements (->> (client/get (str "https://connect.squareup.com/v1/" (:square-location/square-id location) "/settlements")
|
||||
{:headers (client-base-headers client)
|
||||
:query-params {"begin_time" start-date
|
||||
"end_time" end-date}
|
||||
:as :json})
|
||||
@@ -324,22 +306,17 @@
|
||||
settlements)))
|
||||
set
|
||||
seq
|
||||
(map (fn [s]
|
||||
[l s]))
|
||||
(get-settlement-details client)
|
||||
)))
|
||||
(get-settlement-details client location))))
|
||||
|
||||
(defn daily-settlements
|
||||
([client] (daily-settlements client
|
||||
(get-in env [:square-config client :square-location])))
|
||||
([client location-id]
|
||||
(->> (for [settlement (settlements client location-id)]
|
||||
([client location]
|
||||
(->> (for [settlement (settlements client location)]
|
||||
#:expected-deposit {:external-id (str "square/settlement/" (:id settlement))
|
||||
:vendor :vendor/ccp-square
|
||||
:status :expected-deposit-status/pending
|
||||
:total (amount->money (:total_money settlement))
|
||||
:client [:client/code client]
|
||||
:location (get-in env [:square-config client :location])
|
||||
:client (:db/id client)
|
||||
:location (:square-location/client-location location)
|
||||
:fee (- (reduce + 0.0 (map (fn [entry]
|
||||
(if (= (:type entry) "REFUND")
|
||||
(- (amount->money (:fee_money entry)))
|
||||
@@ -354,49 +331,47 @@
|
||||
(filter :expected-deposit/date))))
|
||||
|
||||
(defn refunds
|
||||
([client]
|
||||
(refunds client (get-in env [:square-config client :square-location])))
|
||||
([client l]
|
||||
(let [refunds (:refunds (:body (client/get (str "https://connect.squareup.com/v2/refunds?location_id=" l)
|
||||
{:headers (base-headers client)
|
||||
:as :json
|
||||
:retry-handler (fn [ex try-count http-context]
|
||||
(log/warn "Retrying after failure " ex)
|
||||
(if (> try-count 4) false true))})))]
|
||||
(->> refunds
|
||||
(filter (fn [r] (= "COMPLETED" (:status r))))
|
||||
(map (fn [r]
|
||||
#:sales-refund {:external-id (str "square/refund/" (:id r))
|
||||
:vendor :vendor/ccp-square
|
||||
:total (amount->money (:amount_money r))
|
||||
:fee (transduce
|
||||
(comp (filter #(= "ADJUSTMENT" (:type %)))
|
||||
(map :amount_money)
|
||||
(map amount->money))
|
||||
+
|
||||
0.0
|
||||
(:processing_fee r))
|
||||
:client [:client/code client]
|
||||
:location (get-in env [:square-config client :location])
|
||||
:date (coerce/to-date (:created_at r))
|
||||
:type (:source_type (get-payment client (:payment_id r)))}))))))
|
||||
(let [refunds (:refunds (:body (client/get (str "https://connect.squareup.com/v2/refunds?location_id=" (:square-location/square-id l))
|
||||
{:headers (client-base-headers client)
|
||||
:as :json
|
||||
:retry-handler retry-4})))]
|
||||
(->> refunds
|
||||
(filter (fn [r] (= "COMPLETED" (:status r))))
|
||||
(map (fn [r]
|
||||
#:sales-refund {:external-id (str "square/refund/" (:id r))
|
||||
:vendor :vendor/ccp-square
|
||||
:total (amount->money (:amount_money r))
|
||||
:fee (transduce
|
||||
(comp (filter #(= "ADJUSTMENT" (:type %)))
|
||||
(map :amount_money)
|
||||
(map amount->money))
|
||||
+
|
||||
0.0
|
||||
(:processing_fee r))
|
||||
:client (:db/id client)
|
||||
:location (:square-location/client-location l)
|
||||
:date (coerce/to-date (:created_at r))
|
||||
:type (:source_type (get-payment client (:payment_id r)))}))))))
|
||||
|
||||
(defn upsert
|
||||
([client ]
|
||||
(upsert client nil))
|
||||
([client d]
|
||||
(doseq [square-location (:client/square-locations client)
|
||||
:when (:square-location/client-location square-location)]
|
||||
(upsert client square-location nil)))
|
||||
([client location d]
|
||||
(lc/with-context {:source "Square loading"}
|
||||
(try
|
||||
(let [existing (->> (d/query {:query {:find ['?external-id]
|
||||
:in ['$ '?client]
|
||||
:where ['[?o :sales-order/client ?client]
|
||||
'[?o :sales-order/external-id ?external-id]]}
|
||||
:args [(d/db conn) [:client/code client]]})
|
||||
(let [existing (->> (d/query {:query {:find ['?external-id]
|
||||
:in ['$ '?client]
|
||||
:where ['[?o :sales-order/client ?client]
|
||||
'[?o :sales-order/external-id ?external-id]]}
|
||||
:args [(d/db conn) (:db/id client)]})
|
||||
(map first)
|
||||
set)
|
||||
_ (log/info (count existing) "Sales orders already exist")
|
||||
_ (log/info (count existing) "Sales orders already exist")
|
||||
to-create (filter #(not (existing (:sales-order/external-id %)))
|
||||
(daily-results client d))]
|
||||
(daily-results client location d))]
|
||||
(doseq [x (partition-all 20 to-create)]
|
||||
(log/info "Loading " (count x))
|
||||
@(d/transact conn x)))
|
||||
@@ -404,20 +379,23 @@
|
||||
(log/error e))))))
|
||||
|
||||
(defn upsert-settlements
|
||||
([client] (upsert-settlements client (get-in env [:square-config client :square-location])))
|
||||
([client location-id]
|
||||
([client]
|
||||
(doseq [square-location (:client/square-locations client)
|
||||
:when (:square-location/client-location square-location)]
|
||||
(upsert-settlements client square-location)))
|
||||
([client location]
|
||||
(lc/with-context {:source "Square settlements loading"}
|
||||
(try
|
||||
(let [existing (->> (d/query {:query {:find ['?external-id]
|
||||
:in ['$ '?client]
|
||||
:where ['[?d :expected-deposit/client ?client]
|
||||
'[?d :expected-deposit/external-id ?external-id]]}
|
||||
:args [(d/db conn) [:client/code client]]})
|
||||
:args [(d/db conn) (:db/id client)]})
|
||||
(map first)
|
||||
set)
|
||||
_ (log/info (count existing) "settlements already exist")
|
||||
to-create (filter #(not (existing (:expected-deposit/external-id %)))
|
||||
(daily-settlements client location-id))]
|
||||
(daily-settlements client location))]
|
||||
(doseq [x (partition-all 20 to-create)]
|
||||
(log/info "Loading expected deposit" (count x))
|
||||
@(d/transact conn x)))
|
||||
@@ -426,16 +404,20 @@
|
||||
(log/info "Done loading settlements"))))
|
||||
|
||||
(defn upsert-refunds
|
||||
([client] (upsert-refunds client (get-in env [:square-config client :square-location])))
|
||||
([client]
|
||||
(doseq [square-location (:client/square-locations client)
|
||||
:when (:square-location/client-location square-location)]
|
||||
(upsert-refunds client square-location)))
|
||||
([client location]
|
||||
(lc/with-context {:source "Loading Square Settlements"
|
||||
:client client}
|
||||
:client (:client/code client)
|
||||
:location (:square-location/client-location client)}
|
||||
(try
|
||||
(let [existing (->> (d/query {:query {:find ['?external-id]
|
||||
:in ['$ '?client]
|
||||
:where ['[?r :sales-refund/client ?client]
|
||||
'[?r :sales-refund/external-id ?external-id]]}
|
||||
:args [(d/db conn) [:client/code client]]})
|
||||
:args [(d/db conn) (:db/id client)]})
|
||||
(map first)
|
||||
set)
|
||||
_ (log/info (count existing) "refunds already exist")
|
||||
@@ -448,6 +430,37 @@
|
||||
(log/error e)))
|
||||
(log/info "Done loading refunds"))))
|
||||
|
||||
(def square-read [:db/id
|
||||
:client/code
|
||||
:client/square-auth-token
|
||||
{:client/square-locations [:db/id :square-location/name :square-location/square-id :square-location/client-location]}])
|
||||
|
||||
(defn get-square-clients []
|
||||
(d/q '[:find [(pull ?c [:db/id
|
||||
:client/code
|
||||
:client/square-auth-token
|
||||
{:client/square-locations [:db/id :square-location/name :square-location/square-id :square-location/client-location]}]) ...]
|
||||
:where [?c :client/square-auth-token]]
|
||||
(d/db conn)))
|
||||
|
||||
(defn upsert-locations
|
||||
([] (doseq [client (get-square-clients)]
|
||||
(upsert-locations client)))
|
||||
([client]
|
||||
(let [square-id->id (into {}
|
||||
(map
|
||||
(fn [sl]
|
||||
[(:square-location/square-id sl)
|
||||
(:db/id sl)])
|
||||
(:client/square-locations client)))]
|
||||
(->> (for [square-location (client-locations client)]
|
||||
{:db/id (or (square-id->id (:id square-location)) (d/tempid :db.part/user))
|
||||
:client/_square-locations (:db/id client)
|
||||
:square-location/name (:name square-location)
|
||||
:square-location/square-id (:id square-location)})
|
||||
(d/transact conn)
|
||||
deref))))
|
||||
|
||||
(defn reset []
|
||||
(->>
|
||||
(d/query {:query {:find ['?e]
|
||||
@@ -458,17 +471,17 @@
|
||||
(map (fn [x] [:db/retractEntity x]))))
|
||||
|
||||
(defn upsert-all []
|
||||
(doseq [[client-code] (get-in env [:square-config])
|
||||
:when (d/entid (d/db conn) [:client/code client-code])]
|
||||
(lc/with-context {:source (str "Square loading for " client-code)
|
||||
:client client-code}
|
||||
(doseq [client (get-square-clients)
|
||||
:when (seq (filter :square-location/client-location (:client/square-locations client)))]
|
||||
(lc/with-context {:source "Square loading"
|
||||
:client (:client/code client)}
|
||||
(upsert-locations client)
|
||||
(log/info "Loading Orders")
|
||||
(upsert client-code)
|
||||
(upsert client)
|
||||
(log/info "Loading Settlements")
|
||||
(upsert-settlements client-code)
|
||||
(upsert-settlements client)
|
||||
(log/info "Loading refunds")
|
||||
(upsert-refunds client-code)
|
||||
)))
|
||||
(upsert-refunds client))))
|
||||
|
||||
(mount/defstate square-loader
|
||||
:start (scheduler/every (* 4 59 60 1000) upsert-all)
|
||||
@@ -478,18 +491,4 @@
|
||||
|
||||
|
||||
|
||||
(comment
|
||||
(daily-results)
|
||||
(mount/stop (mount/only #{'auto-ap.square.core/square-settlement-loader}))
|
||||
|
||||
(mount/stop (mount/only #{'auto-ap.square.core/square-refund-loader}))
|
||||
|
||||
(mount/stop (mount/only #{'auto-ap.square.core/square-loader}))
|
||||
|
||||
(mount/start (mount/only #{'auto-ap.square.core/square-settlement-loader}))
|
||||
(mount/start (mount/only #{'auto-ap.square.core/square-refund-loader}))
|
||||
(mount/start (mount/only #{'auto-ap.square.core/square-loader}))
|
||||
(do (upsert) nil)
|
||||
|
||||
(do @(d/transact conn (reset)) nil))
|
||||
|
||||
|
||||
Reference in New Issue
Block a user