allow custom sales export.

This commit is contained in:
Bryce Covert
2021-05-21 16:55:04 -07:00
parent 8aed733826
commit 4dc66f3d86
2 changed files with 221 additions and 194 deletions

View File

@@ -53,7 +53,7 @@
(defroutes api-routes (defroutes api-routes
(context "/api" [] (context "/api" []
exports/routes exports/export-routes
yodlee/routes yodlee/routes
yodlee2/routes yodlee2/routes
invoices/routes invoices/routes

View File

@@ -4,217 +4,244 @@
[auto-ap.datomic.ledger :as d-ledger] [auto-ap.datomic.ledger :as d-ledger]
[auto-ap.datomic.transactions :as d-transactions] [auto-ap.datomic.transactions :as d-transactions]
[auto-ap.datomic.vendors :as d-vendors] [auto-ap.datomic.vendors :as d-vendors]
[buddy.sign.jwt :as jwt]
[auto-ap.graphql :as graphql] [auto-ap.graphql :as graphql]
[auto-ap.graphql.utils :refer [->graphql <-graphql assert-admin]] [auto-ap.graphql.utils :refer [->graphql <-graphql assert-admin assert-can-see-client]]
[auto-ap.routes.utils :refer [wrap-secure]] [auto-ap.routes.utils :refer [wrap-secure]]
[clojure.tools.logging :as log] [clojure.tools.logging :as log]
[auto-ap.logging :refer [error-event info-event warn-event]] [auto-ap.logging :refer [error-event info-event warn-event]]
[clj-time.coerce :as coerce :refer [to-date]] [clj-time.coerce :as coerce :refer [to-date]]
[clj-time.core :as time] [clj-time.core :as time]
[compojure.core :refer [context defroutes GET wrap-routes]] [config.core :refer [env]]
[compojure.core :refer [context defroutes GET wrap-routes routes]]
[datomic.api :as d] [datomic.api :as d]
[ring.middleware.json :refer [wrap-json-response]] [ring.middleware.json :refer [wrap-json-response]]
[venia.core :as venia] [venia.core :as venia]
[yang.time :refer [time-it]])) [yang.time :refer [time-it]]))
(defroutes routes (def api-key-authed-routes
(wrap-routes (context "/" []
(wrap-routes (GET "/sales/aggregated/export" {:keys [query-params identity :as params]}
(context "/" [] (let [client-id (Long/parseLong (get query-params "client-id"))
(GET "/invoices/export" {:keys [query-params identity] :as request} identity (jwt/unsign (get query-params "key") (:jwt-secret env) {:alg :hs512})]
(assert-admin identity) (assert-can-see-client identity client-id)
(let [query [[:all_invoices (into (list)
{:client-code (query-params "client-code") (d/query {:query {:find '[?d4 (sum ?total) (sum ?tax) (sum ?tip) (sum ?service-charge)]
:original-id (query-params "original")} :in '[$ ?c]
:where '[[?s :sales-order/client ?c]
[:id :total :outstanding-balance :invoice-number :date :status :original-id [?s :sales-order/date ?d]
[:payments [:amount [:payment [:check-number :memo [:bank_account [:id :name :number :bank-name :bank-code :code]]]]]] [?s :sales-order/total ?total]
[:vendor [:name :id [:primary_contact [:name]] [:address [:street1 :city :state :zip]]]] [?s :sales-order/tax ?tax]
[:expense_accounts [:amount :id :location [?s :sales-order/tip ?tip]
[:account [:id :numeric-code :name]]]] [?s :sales-order/service-charge ?service-charge]
[:client [:name :id :code :locations]]]]] [(clj-time.coerce/to-date-time ?d) ?d2]
invoices (graphql/query identity (venia/graphql-query {:venia/queries (->graphql query)}))] [(auto-ap.time/localize ?d2) ?d3]
[(auto-ap.time/unparse ?d3 auto-ap.time/normal-date) ?d4]]}
(list (:all-invoices (:data invoices))))) :args [(d/db conn) client-id]}))))))
(GET "/payments/export" {:keys [query-params identity]}
(assert-admin identity)
(let [query [[:all_payments
{:client-code (query-params "client-code")
:original-id (query-params "original")}
[:id :check-number :amount :memo :date :status :type :original-id
[:invoices [[:invoice [:id :original-id]] :amount]]
[:bank-account [:number :code :bank-name :bank-code :id]]
[:vendor [:name :id [:primary-contact [:name :email :phone]] [:default-account [:name :numeric-code :id]] [:address [:street1 :city :state :zip]]]]
[:client [:id :name :code]]
]]]
payments (graphql/query identity (venia/graphql-query {:venia/queries (->graphql query)}))]
(list (:all-payments (:data payments)))))
(GET "/sales/export" {:keys [query-params identity]} (def admin-only-routes
(assert-admin identity) (context "/" []
(let [query [[:all_sales_orders (GET "/invoices/export" {:keys [query-params identity] :as request}
(cond-> {:client-code (query-params "client-code")} (assert-admin identity)
(query-params "after") (assoc :date-range {:start (query-params "after") (let [query [[:all_invoices
:end nil})) {:client-code (query-params "client-code")
[:id :original-id (query-params "original")}
:location
:external_id [:id :total :outstanding-balance :invoice-number :date :status :original-id
:total [:payments [:amount [:payment [:check-number :memo [:bank_account [:id :name :number :bank-name :bank-code :code]]]]]]
:tip [:vendor [:name :id [:primary_contact [:name]] [:address [:street1 :city :state :zip]]]]
:tax [:expense_accounts [:amount :id :location
:discount [:account [:id :numeric-code :name]]]]
:returns [:client [:name :id :code :locations]]]]]
:service_charge invoices (graphql/query identity (venia/graphql-query {:venia/queries (->graphql query)}))]
:date
[:charges [:type_name :total :tip]]
[:line_items [:item_name :total :tax :discount :category]]
[:client [:id :name :code]]]]]
payments (graphql/query identity (venia/graphql-query {:venia/queries (->graphql query)}))
parsedouble #(some-> % Double/parseDouble) ]
(seq (map
(fn [s]
(-> s
(assoc :utc_date (:date s))
(update :date (fn [d]
(coerce/to-string (coerce/to-local-date-time (time/to-time-zone (coerce/to-date-time d) (time/time-zone-for-id "America/Los_Angeles"))))))
(update :total parsedouble)
(update :tax parsedouble)
(update :discount parsedouble)
(update :tip parsedouble)
(update :line-items (fn [lis]
(map
(fn [li]
(-> li
(update :tax parsedouble)
(update :discount parsedouble)
(update :total parsedouble)))
lis)))
(update :charges (fn [charges]
(map
(fn [charge]
(-> charge
(update :tip parsedouble)
(update :total parsedouble)))
charges)))))
(:all-sales-orders (:data payments))))))
(GET "/expected-deposit/export" {:keys [query-params identity]}
(assert-admin identity)
(let [query [[:all_expected_deposits
(cond-> {:client-code (query-params "client-code")}
(query-params "after") (assoc :date-range {:start (query-params "after")
:end nil}))
[:id
[:client [:id :name :code]]
:location
:external_id
:total
:fee
:date]]]
payments (graphql/query identity (venia/graphql-query {:venia/queries (->graphql query)}))]
(seq (map
(fn [d]
(-> d
(update :fee #(some-> % Double/parseDouble))
(update :total #(some-> % Double/parseDouble))))
(:all-expected-deposits (:data payments))))))
(GET "/clients/export" {:keys [query-params identity]}
(assert-admin identity)
(map <-graphql (d-clients/get-all)))
(GET "/vendors/export" {:keys [query-params identity]}
(assert-admin identity)
(map <-graphql (d-vendors/get-graphql {})))
(GET "/ledger/export" {:keys [query-params identity]}
(log/info "exporting for " (query-params "client-code"))
(assert-admin identity)
(let [[result time] (time-it (transduce (comp
(map #(update % :journal-entry/date to-date))
(map <-graphql))
conj
(list)
(first (d-ledger/get-graphql {:count Integer/MAX_VALUE
:client-code (query-params "client-code")}))))]
(info-event "Export completed"
{:time (:time time)
:errors (seq (:errors result))})
result))
(GET "/accounts/export" {:keys [query-params identity]}
(assert-admin identity)
(let [client-id (d-clients/code->id (query-params "client-code")) (list (:all-invoices (:data invoices)))))
query [[:accounts (GET "/payments/export" {:keys [query-params identity]}
[:id :numeric_code :type :applicability :location :name [:client_overrides [:name [:client [:id :code :name]]]]]]] (assert-admin identity)
all-accounts (graphql/query identity (venia/graphql-query {:venia/queries (->graphql query)}))] (let [query [[:all_payments
{:client-code (query-params "client-code")
:original-id (query-params "original")}
[:id :check-number :amount :memo :date :status :type :original-id
[:invoices [[:invoice [:id :original-id]] :amount]]
[:bank-account [:number :code :bank-name :bank-code :id]]
[:vendor [:name :id [:primary-contact [:name :email :phone]] [:default-account [:name :numeric-code :id]] [:address [:street1 :city :state :zip]]]]
[:client [:id :name :code]]
]]]
payments (graphql/query identity (venia/graphql-query {:venia/queries (->graphql query)}))]
(list (:all-payments (:data payments)))))
(list (transduce (GET "/sales/export" {:keys [query-params identity :as params]}
(comp (assert-admin identity)
(filter (fn [a] (println params)
(let [overriden-clients (set (map (comp :id :client) (:client-overrides a)))] (let [query [[:all_sales_orders
(or (= :global (:applicability a)) (cond-> {:client-code (query-params "client-code")}
(overriden-clients (str client-id)))))) (query-params "after") (assoc :date-range {:start (query-params "after")
(map (fn [a] :end nil}))
(let [client->name (reduce [:id
(fn [override co] :location
(assoc override (str (:id (:client co))) (:name co))) :external_id
{} :total
(:client-overrides a))] :tip
(-> a :tax
(assoc :global-name (:name a)) :discount
(assoc :client-name (client->name (str client-id) (:name a))) :returns
(dissoc :client-overrides)))))) :service_charge
conj :date
[] [:charges [:type_name :total :tip]]
(:accounts (:data all-accounts)))))) [:line_items [:item_name :total :tax :discount :category]]
[:client [:id :name :code]]]]]
payments (graphql/query identity (venia/graphql-query {:venia/queries (->graphql query)}))
parsedouble #(some-> % Double/parseDouble) ]
(seq (map
(fn [s]
(-> s
(assoc :utc_date (:date s))
(update :date (fn [d]
(coerce/to-string (coerce/to-local-date-time (time/to-time-zone (coerce/to-date-time d) (time/time-zone-for-id "America/Los_Angeles"))))))
(update :total parsedouble)
(update :tax parsedouble)
(update :discount parsedouble)
(update :tip parsedouble)
(update :line-items (fn [lis]
(map
(fn [li]
(-> li
(update :tax parsedouble)
(update :discount parsedouble)
(update :total parsedouble)))
lis)))
(update :charges (fn [charges]
(map
(fn [charge]
(-> charge
(update :tip parsedouble)
(update :total parsedouble)))
charges)))))
(:all-sales-orders (:data payments))))))
(GET "/transactions/export" {:keys [query-params identity]}
(assert-admin identity)
(let [[transactions] (d-transactions/get-graphql {:client-code (query-params "client-code") (GET "/expected-deposit/export" {:keys [query-params identity]}
(assert-admin identity)
(let [query [[:all_expected_deposits
(cond-> {:client-code (query-params "client-code")}
(query-params "after") (assoc :date-range {:start (query-params "after")
:end nil}))
[:id
[:client [:id :name :code]]
:location
:external_id
:total
:fee
:date]]]
payments (graphql/query identity (venia/graphql-query {:venia/queries (->graphql query)}))]
(seq (map
(fn [d]
(-> d
(update :fee #(some-> % Double/parseDouble))
(update :total #(some-> % Double/parseDouble))))
(:all-expected-deposits (:data payments))))))
(GET "/clients/export" {:keys [query-params identity]}
(assert-admin identity)
(map <-graphql (d-clients/get-all)))
(GET "/vendors/export" {:keys [query-params identity]}
(assert-admin identity)
(map <-graphql (d-vendors/get-graphql {})))
(GET "/ledger/export" {:keys [query-params identity]}
(log/info "exporting for " (query-params "client-code"))
(assert-admin identity)
(let [[result time] (time-it (transduce (comp
(map #(update % :journal-entry/date to-date))
(map <-graphql))
conj
(list)
(first (d-ledger/get-graphql {:count Integer/MAX_VALUE
:client-code (query-params "client-code")}))))]
(info-event "Export completed"
{:time (:time time)
:errors (seq (:errors result))})
result))
(GET "/accounts/export" {:keys [query-params identity]}
(assert-admin identity)
(let [client-id (d-clients/code->id (query-params "client-code"))
query [[:accounts
[:id :numeric_code :type :applicability :location :name [:client_overrides [:name [:client [:id :code :name]]]]]]]
all-accounts (graphql/query identity (venia/graphql-query {:venia/queries (->graphql query)}))]
(list (transduce
(comp
(filter (fn [a]
(let [overriden-clients (set (map (comp :id :client) (:client-overrides a)))]
(or (= :global (:applicability a))
(overriden-clients (str client-id))))))
(map (fn [a]
(let [client->name (reduce
(fn [override co]
(assoc override (str (:id (:client co))) (:name co)))
{}
(:client-overrides a))]
(-> a
(assoc :global-name (:name a))
(assoc :client-name (client->name (str client-id) (:name a)))
(dissoc :client-overrides))))))
conj
[]
(:accounts (:data all-accounts))))))
(GET "/transactions/export" {:keys [query-params identity]}
(assert-admin identity)
(let [[transactions] (d-transactions/get-graphql {:client-code (query-params "client-code")
#_#_:original-id (Integer/parseInt (query-params "original")) #_#_:original-id (Integer/parseInt (query-params "original"))
:count Integer/MAX_VALUE})] :count Integer/MAX_VALUE})]
(map (comp ->graphql (fn [i] (map (comp ->graphql (fn [i]
(cond-> i (cond-> i
true (update :transaction/date to-date) true (update :transaction/date to-date)
true (update :transaction/post-date to-date) true (update :transaction/post-date to-date)
(:transaction/payment i) (update-in [:transaction/payment :payment/date] to-date) (:transaction/payment i) (update-in [:transaction/payment :payment/date] to-date)
))) )))
transactions))) transactions)))
(GET "/transactions/export2" {:keys [query-params identity]} (GET "/transactions/export2" {:keys [query-params identity]}
(assert-admin identity) (assert-admin identity)
(let [db (d/db conn)] (let [db (d/db conn)]
(->> (->>
(d/query {:query {:find ['?e] (d/query {:query {:find ['?e]
:in ['$ '?client-code] :in ['$ '?client-code]
:where ['[?e :transaction/client ?client-code]]} :where ['[?e :transaction/client ?client-code]]}
:args [db [:client/code (query-params "client-code")]]}) :args [db [:client/code (query-params "client-code")]]})
(map first) (map first)
(map (fn [e] (map (fn [e]
(let [e (d/entity db e) (let [e (d/entity db e)
client (:transaction/client e) client (:transaction/client e)
bank-account (:transaction/bank-account e)] bank-account (:transaction/bank-account e)]
{:id (:db/id e) {:id (:db/id e)
:date (:transaction/date e) :date (:transaction/date e)
:post_date (:transaction/post-date e) :post_date (:transaction/post-date e)
:client { :code (:client/code client) :client { :code (:client/code client)
:id (:db/id client) :id (:db/id client)
:name (:client/name client)} :name (:client/name client)}
:amount (:transaction/amount e) :amount (:transaction/amount e)
:description_original (:transaction/description-original e) :description_original (:transaction/description-original e)
:approval_status (:transaction/approval-status e) :approval_status (:transaction/approval-status e)
:bank_account {:name (:bank-account/name bank-account) :bank_account {:name (:bank-account/name bank-account)
:code (:bank-account/code bank-account) :code (:bank-account/code bank-account)
:id (:db/id bank-account)}})))))) :id (:db/id bank-account)}}))))))
(GET "/raw" {:keys [query-params identity]} (GET "/raw" {:keys [query-params identity]}
(assert-admin identity) (assert-admin identity)
(log/info "Executing raw query " (get query-params "query" )) (log/info "Executing raw query " (get query-params "query" ))
(into (list) (apply d/q (clojure.edn/read-string (get query-params "query" )) (into [(d/db conn)] (clojure.edn/read-string (get query-params "args" "[]"))))))) (into (list) (apply d/q (clojure.edn/read-string (get query-params "query" )) (into [(d/db conn)] (clojure.edn/read-string (get query-params "args" "[]"))))))))
(defroutes export-routes
(wrap-routes
(routes
api-key-authed-routes
(wrap-routes admin-only-routes wrap-secure))
wrap-secure)
wrap-json-response)) wrap-json-response))