Revamps all of the IOL's routing, so that the new history page can share with the rest.
This commit is contained in:
@@ -1,11 +1,11 @@
|
||||
(ns auto-ap.routes.auth
|
||||
(:require [auto-ap.datomic.users :as users]
|
||||
[buddy.sign.jwt :as jwt]
|
||||
[clj-http.client :as http]
|
||||
[clj-time.core :as time]
|
||||
[compojure.core :refer [GET defroutes]]
|
||||
[config.core :refer [env]]
|
||||
[clojure.tools.logging :as log]))
|
||||
(:require
|
||||
[auto-ap.datomic.users :as users]
|
||||
[buddy.sign.jwt :as jwt]
|
||||
[clj-http.client :as http]
|
||||
[clj-time.core :as time]
|
||||
[clojure.tools.logging :as log]
|
||||
[config.core :refer [env]]))
|
||||
|
||||
(def google-client-id "264081895820-0nndcfo3pbtqf30sro82vgq5r27h8736.apps.googleusercontent.com")
|
||||
(def google-client-secret "OC-WemHurPXYpuIw5cT-B90g")
|
||||
@@ -19,48 +19,50 @@
|
||||
(:jwt-secret env)
|
||||
{:alg :hs512}))
|
||||
|
||||
(defroutes routes
|
||||
(GET "/oauth" {{:strs [code]} :query-params {:strs [host]} :headers}
|
||||
(try
|
||||
(let [auth (-> "https://accounts.google.com/o/oauth2/token"
|
||||
(http/post
|
||||
{:form-params {"client_id" google-client-id
|
||||
"client_secret" google-client-secret
|
||||
"code" code
|
||||
"redirect_uri" (str (:scheme env) "://" host "/api/oauth")
|
||||
"grant_type" "authorization_code"}
|
||||
:as :json})
|
||||
:body)
|
||||
token (:access_token auth)
|
||||
profile (-> (http/get "https://www.googleapis.com/oauth2/v1/userinfo"
|
||||
{:headers {"Authorization" (str "Bearer " token)} :as :json})
|
||||
:body)
|
||||
user (users/find-or-insert! {:user/provider "google"
|
||||
:user/provider-id (:id profile)
|
||||
:user/role :user-role/none
|
||||
:user/name (:name profile)})
|
||||
auth {:user (:name profile)
|
||||
:exp (time/plus (time/now) (time/days 30))
|
||||
:user/clients (map (fn [c]
|
||||
(select-keys c [:client/code :db/id :client/name :client/locations]))
|
||||
(:user/clients user))
|
||||
:user/role (name (:user/role user))
|
||||
:user/name (:name profile)}
|
||||
]
|
||||
(log/info "authenticated as user" user)
|
||||
;; TODO - these namespaces are not being transmitted/deserialized properly
|
||||
|
||||
(if (and token user)
|
||||
(let [jwt (jwt/sign auth
|
||||
(:jwt-secret env)
|
||||
{:alg :hs512})]
|
||||
|
||||
{:status 301
|
||||
:headers {"Location" (str "/?jwt=" jwt)}
|
||||
:session {:identity (dissoc auth :exp)}})
|
||||
{:status 401
|
||||
:body "Couldn't authenticate"}))
|
||||
(catch Exception e
|
||||
(log/warn e )
|
||||
{:status 401
|
||||
:body (str "Couldn't authenticate " (.toString e))}))))
|
||||
(defn oauth [{{:strs [code]} :query-params {:strs [host]} :headers}]
|
||||
(try
|
||||
(let [auth (-> "https://accounts.google.com/o/oauth2/token"
|
||||
(http/post
|
||||
{:form-params {"client_id" google-client-id
|
||||
"client_secret" google-client-secret
|
||||
"code" code
|
||||
"redirect_uri" (str (:scheme env) "://" host "/api/oauth")
|
||||
"grant_type" "authorization_code"}
|
||||
:as :json})
|
||||
:body)
|
||||
token (:access_token auth)
|
||||
profile (-> (http/get "https://www.googleapis.com/oauth2/v1/userinfo"
|
||||
{:headers {"Authorization" (str "Bearer " token)} :as :json})
|
||||
:body)
|
||||
user (users/find-or-insert! {:user/provider "google"
|
||||
:user/provider-id (:id profile)
|
||||
:user/role :user-role/none
|
||||
:user/name (:name profile)})
|
||||
auth {:user (:name profile)
|
||||
:exp (time/plus (time/now) (time/days 30))
|
||||
:user/clients (map (fn [c]
|
||||
(select-keys c [:client/code :db/id :client/name :client/locations]))
|
||||
(:user/clients user))
|
||||
:user/role (name (:user/role user))
|
||||
:user/name (:name profile)}
|
||||
]
|
||||
(log/info "authenticated as user" user)
|
||||
;; TODO - these namespaces are not being transmitted/deserialized properly
|
||||
|
||||
(if (and token user)
|
||||
(let [jwt (jwt/sign auth
|
||||
(:jwt-secret env)
|
||||
{:alg :hs512})]
|
||||
|
||||
{:status 301
|
||||
:headers {"Location" (str "/?jwt=" jwt)}
|
||||
:session {:identity (dissoc auth :exp)}})
|
||||
{:status 401
|
||||
:body "Couldn't authenticate"}))
|
||||
(catch Exception e
|
||||
(log/warn e )
|
||||
{:status 401
|
||||
:body (str "Couldn't authenticate " (.toString e))})))
|
||||
|
||||
(def routes {"api" {"/oauth" :oauth}})
|
||||
(def match->handler {:oauth oauth})
|
||||
|
||||
@@ -11,13 +11,13 @@
|
||||
[auto-ap.routes.utils :refer [wrap-secure]]
|
||||
[auto-ap.time :as atime]
|
||||
[buddy.sign.jwt :as jwt]
|
||||
[cheshire.generate :as generate]
|
||||
[clj-time.coerce :as coerce :refer [to-date]]
|
||||
[clj-time.core :as time]
|
||||
[clojure.data.csv :as csv]
|
||||
[clojure.edn :refer [read-string]]
|
||||
[clojure.tools.logging :as log]
|
||||
[com.unbounce.dogstatsd.core :as statsd]
|
||||
[compojure.core :refer [context defroutes GET routes wrap-routes]]
|
||||
[config.core :refer [env]]
|
||||
[datomic.api :as d]
|
||||
[ring.middleware.json :refer [wrap-json-response]]
|
||||
@@ -30,25 +30,25 @@
|
||||
(csv/write-csv w %)
|
||||
(.toString w))))))
|
||||
|
||||
(def api-key-authed-routes
|
||||
(context "/" []
|
||||
(GET "/sales/aggregated/export" {:keys [query-params]}
|
||||
(let [client-id (Long/parseLong (get query-params "client-id"))
|
||||
identity (jwt/unsign (get query-params "key") (:jwt-secret env) {:alg :hs512})]
|
||||
(assert-can-see-client identity client-id)
|
||||
(into (list)
|
||||
(d/query {:query {:find '[?d4 (sum ?total) (sum ?tax) (sum ?tip) (sum ?service-charge)]
|
||||
:in '[$ ?c]
|
||||
:where '[[?s :sales-order/client ?c]
|
||||
[?s :sales-order/date ?d]
|
||||
[?s :sales-order/total ?total]
|
||||
[?s :sales-order/tax ?tax]
|
||||
[?s :sales-order/tip ?tip]
|
||||
[?s :sales-order/service-charge ?service-charge]
|
||||
[(clj-time.coerce/to-date-time ?d) ?d2]
|
||||
[(auto-ap.time/localize ?d2) ?d3]
|
||||
[(auto-ap.time/unparse ?d3 auto-ap.time/normal-date) ?d4]]}
|
||||
:args [(d/db conn) client-id]}))))))
|
||||
(defn aggregated-sales-export [{:keys [query-params]}]
|
||||
(let [client-id (Long/parseLong (get query-params "client-id"))
|
||||
identity (jwt/unsign (get query-params "key") (:jwt-secret env) {:alg :hs512})]
|
||||
(assert-can-see-client identity client-id)
|
||||
(into (list)
|
||||
(d/query {:query {:find '[?d4 (sum ?total) (sum ?tax) (sum ?tip) (sum ?service-charge)]
|
||||
:in '[$ ?c]
|
||||
:where '[[?s :sales-order/client ?c]
|
||||
[?s :sales-order/date ?d]
|
||||
[?s :sales-order/total ?total]
|
||||
[?s :sales-order/tax ?tax]
|
||||
[?s :sales-order/tip ?tip]
|
||||
[?s :sales-order/service-charge ?service-charge]
|
||||
[(clj-time.coerce/to-date-time ?d) ?d2]
|
||||
[(auto-ap.time/localize ?d2) ?d3]
|
||||
[(auto-ap.time/unparse ?d3 auto-ap.time/normal-date) ?d4]]}
|
||||
:args [(d/db conn) client-id]}))))
|
||||
|
||||
|
||||
|
||||
(defn client-tag [params]
|
||||
(when-let [code (or (params "client-code")
|
||||
@@ -82,332 +82,366 @@
|
||||
]))
|
||||
m))
|
||||
|
||||
(def admin-only-routes
|
||||
(context "/" []
|
||||
(GET "/invoices/export" {:keys [query-params identity]}
|
||||
(assert-admin identity)
|
||||
(statsd/time! [(str "export.time") {:tags #{(client-tag query-params)
|
||||
"export:invoice"}}]
|
||||
(list (into (list)
|
||||
(map datomic-map->graphql-map)
|
||||
(d/q '[:find [(pull ?i [:db/id :invoice/total :invoice/outstanding-balance :invoice/invoice-number :invoice/date :invoice/original-id
|
||||
{ :invoice/status [:db/ident]
|
||||
:invoice/payments
|
||||
[:invoice-payment/amount
|
||||
{:invoice-payment/payment [:payment/check-number
|
||||
:payment/memo
|
||||
{:payment/bank_account [:bank-account/id :bank-account/name :bank-account/number :bank-account/bank-name :bank-account/bank-code :bank-account/code]}]}]
|
||||
:invoice/vendor [:vendor/name
|
||||
:db/id
|
||||
{:vendor/primary-contact [:contact/name]
|
||||
:vendor/address [:address/street1 :address/city :address/state :address/zip]}]
|
||||
:invoice/expense-accounts [:db/id
|
||||
:invoice-expense-account/amount
|
||||
:invoice-expense-account/id
|
||||
:invoice-expense-account/location
|
||||
{:invoice-expense-account/account
|
||||
[:db/id :account/numeric-code :account/name]}]
|
||||
:invoice/client [:client/name :db/id :client/code :client/locations]}]) ...]
|
||||
:in $ ?c
|
||||
:where [?i :invoice/client ?c]]
|
||||
(d/db conn)
|
||||
[:client/code (query-params "client-code")])))))
|
||||
(GET "/payments/export" {:keys [query-params identity]}
|
||||
(assert-admin identity)
|
||||
(statsd/time! [(str "export.time") {:tags #{(client-tag query-params)
|
||||
"export:payment"}}]
|
||||
(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))))))
|
||||
(defn export-invoices [{:keys [query-params identity]}]
|
||||
(assert-admin identity)
|
||||
(statsd/time! [(str "export.time") {:tags #{(client-tag query-params)
|
||||
"export:invoice"}}]
|
||||
{:body
|
||||
(list (into (list)
|
||||
(map datomic-map->graphql-map)
|
||||
(d/q '[:find [(pull ?i [:db/id :invoice/total :invoice/outstanding-balance :invoice/invoice-number :invoice/date :invoice/original-id
|
||||
{ :invoice/status [:db/ident]
|
||||
:invoice/payments
|
||||
[:invoice-payment/amount
|
||||
{:invoice-payment/payment [:payment/check-number
|
||||
:payment/memo
|
||||
{:payment/bank_account [:bank-account/id :bank-account/name :bank-account/number :bank-account/bank-name :bank-account/bank-code :bank-account/code]}]}]
|
||||
:invoice/vendor [:vendor/name
|
||||
:db/id
|
||||
{:vendor/primary-contact [:contact/name]
|
||||
:vendor/address [:address/street1 :address/city :address/state :address/zip]}]
|
||||
:invoice/expense-accounts [:db/id
|
||||
:invoice-expense-account/amount
|
||||
:invoice-expense-account/id
|
||||
:invoice-expense-account/location
|
||||
{:invoice-expense-account/account
|
||||
[:db/id :account/numeric-code :account/name]}]
|
||||
:invoice/client [:client/name :db/id :client/code :client/locations]}]) ...]
|
||||
:in $ ?c
|
||||
:where [?i :invoice/client ?c]]
|
||||
(d/db conn)
|
||||
[:client/code (query-params "client-code")])))}))
|
||||
|
||||
(GET "/sales/export" {:keys [query-params identity]}
|
||||
(assert-admin identity)
|
||||
(statsd/time! [(str "export.time") {:tags #{(client-tag query-params)
|
||||
"export:sales"}}]
|
||||
(let [query [[:all_sales_orders
|
||||
(cond-> {:client-code (query-params "client-code")}
|
||||
(query-params "after") (assoc :date-range {:start (query-params "after")
|
||||
:end nil}))
|
||||
[:id
|
||||
:location
|
||||
:external_id
|
||||
:total
|
||||
:tip
|
||||
:tax
|
||||
:discount
|
||||
:returns
|
||||
:service_charge
|
||||
: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)
|
||||
(statsd/time! [(str "export.time") {:tags #{(client-tag query-params)
|
||||
"export:deposit"}}]
|
||||
(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 [identity]}
|
||||
(assert-admin identity)
|
||||
(map <-graphql (d-clients/get-all)))
|
||||
|
||||
(GET "/vendors/export" {:keys [identity]}
|
||||
(assert-admin identity)
|
||||
(statsd/time! [(str "export.time") {:tags #{"export:vendors"}}]
|
||||
(map <-graphql (->> (d/q '[:find [?e ...]
|
||||
:in $
|
||||
:where [?e :vendor/name]]
|
||||
(d/db conn))
|
||||
(d/pull-many (d/db conn) vendor/default-read)))))
|
||||
|
||||
(GET "/vendors/company/export" {:keys [identity query-params]}
|
||||
(statsd/time! [(str "export.time") {:tags #{"export:company-vendors"}}]
|
||||
(let [client (:db/id (d/pull (d/db conn) [:db/id] [:client/code (get query-params "client")]))
|
||||
|
||||
_ (assert-can-see-client identity client)
|
||||
data (->> (d/q '[:find (pull ?v [:vendor/name
|
||||
:vendor/terms
|
||||
{:vendor/default-account [:account/name :account/numeric-code
|
||||
{:account/client-overrides
|
||||
[:account-client-override/client
|
||||
:account-client-override/name]}]
|
||||
:vendor/terms-overrides [:vendor-terms-override/client
|
||||
:vendor-terms-override/terms]
|
||||
:vendor/account-overrides [:vendor-account-override/client
|
||||
{:vendor-account-override/account [:account/numeric-code :account/name
|
||||
{:account/client-overrides
|
||||
[:account-client-override/client
|
||||
:account-client-override/name]}]}]
|
||||
:vendor/address [:address/street1 :address/city :address/state :address/zip]}])
|
||||
:in $ ?c
|
||||
:where [?vu :vendor-usage/client ?c]
|
||||
[?vu :vendor-usage/count ?count]
|
||||
[(>= ?vu 0)]
|
||||
[?vu :vendor-usage/vendor ?v]
|
||||
(not [?v :vendor/hidden true])]
|
||||
(d/db conn)
|
||||
client)
|
||||
(map (fn [[v]]
|
||||
[(-> v :vendor/name)
|
||||
(-> v :vendor/address :address/street1)
|
||||
(-> v :vendor/address :address/city)
|
||||
(-> v :vendor/address :address/state)
|
||||
(-> v :vendor/address :address/zip)
|
||||
(-> v (vendor/terms-for-client-id client) )
|
||||
(-> v (vendor/account-for-client-id client) (accounts/clientize client) :account/name)
|
||||
(-> v (vendor/account-for-client-id client) :account/numeric-code)
|
||||
]
|
||||
))
|
||||
(into [["Vendor Name" "Address" "City" "State" "Zip" "Terms" "Account" "Account Code"]]))]
|
||||
{:body
|
||||
(with-open [w (java.io.StringWriter.)]
|
||||
(csv/write-csv w data
|
||||
:quote? (constantly true))
|
||||
(.toString w))
|
||||
:headers {"Content-Type" "application/csv"}})))
|
||||
(GET "/ledger/export" {:keys [identity query-params]}
|
||||
(let [start-date (or (some-> (query-params "start-date")
|
||||
(atime/parse atime/iso-date))
|
||||
(time/plus (time/now) (time/days -120)))]
|
||||
(log/info "exporting for " (query-params "client-code") "starting" start-date)
|
||||
(assert-admin identity)
|
||||
(statsd/time! [(str "export.time") {:tags #{(client-tag query-params)
|
||||
"export:ledger2"}}]
|
||||
(let [results (->> (d/q '[:find (pull ?e [:db/id
|
||||
:journal-entry/external-id
|
||||
:journal-entry/cleared
|
||||
:journal-entry/alternate-description
|
||||
:journal-entry/date
|
||||
:journal-entry/note
|
||||
:journal-entry/amount
|
||||
:journal-entry/source
|
||||
:journal-entry/cleared-against
|
||||
:journal-entry/original-entity
|
||||
{:journal-entry/client [:client/name :client/code :db/id]
|
||||
:journal-entry/vendor [:vendor/name :db/id]
|
||||
:journal-entry/line-items [:db/id
|
||||
:journal-entry-line/location
|
||||
:journal-entry-line/debit
|
||||
:journal-entry-line/credit
|
||||
{:journal-entry-line/account [:bank-account/include-in-reports
|
||||
:bank-account/bank-name
|
||||
:bank-account/numeric-code
|
||||
:bank-account/code
|
||||
:bank-account/visible
|
||||
:bank-account/name
|
||||
:bank-account/number
|
||||
:account/code
|
||||
:account/name
|
||||
:account/numeric-code
|
||||
:account/location
|
||||
{:account/type [:db/ident :db/id]}
|
||||
{:bank-account/type [:db/ident :db/id]}]}]}])
|
||||
:in $ ?c ?start-date
|
||||
:where [?e :journal-entry/client ?c]
|
||||
[?e :journal-entry/date ?date]
|
||||
[(>= ?date ?start-date)]]
|
||||
(d/db conn)
|
||||
[:client/code (query-params "client-code")]
|
||||
(coerce/to-date start-date)))
|
||||
tf-result (transduce (comp
|
||||
(map first)
|
||||
(filter (fn [je]
|
||||
(every?
|
||||
(fn [jel]
|
||||
(let [include-in-reports (-> jel :journal-entry-line/account :bank-account/include-in-reports)]
|
||||
(or (nil? include-in-reports)
|
||||
(true? include-in-reports))))
|
||||
(:journal-entry/line-items je))))
|
||||
(map <-graphql))
|
||||
conj
|
||||
(list)
|
||||
results)]
|
||||
tf-result))))
|
||||
(defn export-payments [{:keys [query-params identity]}]
|
||||
(assert-admin identity)
|
||||
(statsd/time! [(str "export.time") {:tags #{(client-tag query-params)
|
||||
"export:payment"}}]
|
||||
(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)}))]
|
||||
{:body
|
||||
(list (:all-payments (:data payments)))})))
|
||||
|
||||
|
||||
(defn export-sales [{:keys [query-params identity]}]
|
||||
(assert-admin identity)
|
||||
(statsd/time! [(str "export.time") {:tags #{(client-tag query-params)
|
||||
"export:sales"}}]
|
||||
(let [query [[:all_sales_orders
|
||||
(cond-> {:client-code (query-params "client-code")}
|
||||
(query-params "after") (assoc :date-range {:start (query-params "after")
|
||||
:end nil}))
|
||||
[:id
|
||||
:location
|
||||
:external_id
|
||||
:total
|
||||
:tip
|
||||
:tax
|
||||
:discount
|
||||
:returns
|
||||
:service_charge
|
||||
: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) ]
|
||||
{:body
|
||||
(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 "/accounts/export" {:keys [query-params identity]}
|
||||
(assert-admin identity)
|
||||
(statsd/time! [(str "export.time") {:tags #{(client-tag query-params)
|
||||
"export:accounts"}}]
|
||||
(let [client-id (d-clients/code->id (query-params "client-code"))
|
||||
query [[:all-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)}))]
|
||||
(defn export-expected-deposits [{:keys [query-params identity]}]
|
||||
(assert-admin identity)
|
||||
(statsd/time! [(str "export.time") {:tags #{(client-tag query-params)
|
||||
"export:deposit"}}]
|
||||
(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)}))]
|
||||
{:body
|
||||
(seq (map
|
||||
(fn [d]
|
||||
(-> d
|
||||
(update :fee #(some-> % Double/parseDouble))
|
||||
(update :total #(some-> % Double/parseDouble))))
|
||||
(:all-expected-deposits (:data payments))))})))
|
||||
|
||||
(list (transduce
|
||||
(comp
|
||||
(filter (fn [a]
|
||||
(let [overriden-clients (set (map (comp :id :client) (:client-overrides a)))]
|
||||
(or (nil? (:applicability a))
|
||||
(= :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
|
||||
(list)
|
||||
(:all-accounts (:data all-accounts)))))))
|
||||
|
||||
(GET "/transactions/export" {:keys [query-params identity]}
|
||||
(assert-admin identity)
|
||||
(statsd/time! [(str "export.time") {:tags #{(client-tag query-params)
|
||||
"export:transactions"}}]
|
||||
(let [[transactions] (d-transactions/get-graphql {:client-code (query-params "client-code")
|
||||
#_#_:original-id (Integer/parseInt (query-params "original"))
|
||||
:count Integer/MAX_VALUE})]
|
||||
|
||||
|
||||
(map (comp ->graphql (fn [i]
|
||||
(cond-> i
|
||||
true (update :transaction/date to-date)
|
||||
true (update :transaction/post-date to-date)
|
||||
(:transaction/payment i) (update-in [:transaction/payment :payment/date] to-date)
|
||||
(:transaction/expected-deposit i) (update-in [:transaction/expected-deposit :expected-deposit/date] to-date))))
|
||||
transactions)))
|
||||
)
|
||||
(generate/add-encoder org.joda.time.DateTime
|
||||
(fn [c jsonGenerator]
|
||||
(.writeString jsonGenerator (str c))))
|
||||
|
||||
(GET "/transactions/export2" {:keys [query-params identity]}
|
||||
(assert-admin identity)
|
||||
(statsd/time! [(str "export.time") {:tags #{(client-tag query-params)
|
||||
"export:transactions2"}}]
|
||||
(let [db (d/db conn)]
|
||||
(->>
|
||||
(d/query {:query {:find ['?e]
|
||||
:in ['$ '?client-code]
|
||||
:where ['[?e :transaction/client ?client-code]]}
|
||||
:args [db [:client/code (query-params "client-code")]]})
|
||||
(map first)
|
||||
(map (fn [e]
|
||||
(let [e (d/entity db e)
|
||||
client (:transaction/client e)
|
||||
bank-account (:transaction/bank-account e)]
|
||||
{:id (:db/id e)
|
||||
:date (:transaction/date e)
|
||||
:post_date (:transaction/post-date e)
|
||||
:client { :code (:client/code client)
|
||||
:id (:db/id client)
|
||||
:name (:client/name client)}
|
||||
:amount (:transaction/amount e)
|
||||
:description_original (:transaction/description-original e)
|
||||
:approval_status (:transaction/approval-status e)
|
||||
:bank_account {:name (:bank-account/name bank-account)
|
||||
:code (:bank-account/code bank-account)
|
||||
:id (:db/id bank-account)}})))))))
|
||||
|
||||
(GET "/raw" {:keys [query-params identity]}
|
||||
(assert-admin identity)
|
||||
(log/info "Executing raw query " (get query-params "query" ))
|
||||
(statsd/time! [(str "export.time") {:tags #{"export:raw"}}]
|
||||
(into (list) (apply d/q (read-string (get query-params "query" )) (into [(d/db conn)] (read-string (get query-params "args" "[]")))))))))
|
||||
(defn export-clients[{:keys [identity]}]
|
||||
(assert-admin identity)
|
||||
{:body (into []
|
||||
(map <-graphql)
|
||||
(d-clients/get-all))})
|
||||
|
||||
(defroutes export-routes
|
||||
(routes
|
||||
(wrap-routes api-key-authed-routes
|
||||
wrap-csv-response)
|
||||
(defn export-vendors [{:keys [identity]}]
|
||||
(assert-admin identity)
|
||||
(statsd/time! [(str "export.time") {:tags #{"export:vendors"}}]
|
||||
{:body
|
||||
(map <-graphql (->> (d/q '[:find [?e ...]
|
||||
:in $
|
||||
:where [?e :vendor/name]]
|
||||
(d/db conn))
|
||||
(d/pull-many (d/db conn) vendor/default-read)))}))
|
||||
|
||||
(wrap-routes (wrap-routes admin-only-routes wrap-secure)
|
||||
wrap-json-response)))
|
||||
(defn export-company-vendors [{:keys [identity query-params]}]
|
||||
(statsd/time! [(str "export.time") {:tags #{"export:company-vendors"}}]
|
||||
(let [client (:db/id (d/pull (d/db conn) [:db/id] [:client/code (get query-params "client")]))
|
||||
|
||||
_ (assert-can-see-client identity client)
|
||||
data (->> (d/q '[:find (pull ?v [:vendor/name
|
||||
:vendor/terms
|
||||
{:vendor/default-account [:account/name :account/numeric-code
|
||||
{:account/client-overrides
|
||||
[:account-client-override/client
|
||||
:account-client-override/name]}]
|
||||
:vendor/terms-overrides [:vendor-terms-override/client
|
||||
:vendor-terms-override/terms]
|
||||
:vendor/account-overrides [:vendor-account-override/client
|
||||
{:vendor-account-override/account [:account/numeric-code :account/name
|
||||
{:account/client-overrides
|
||||
[:account-client-override/client
|
||||
:account-client-override/name]}]}]
|
||||
:vendor/address [:address/street1 :address/city :address/state :address/zip]}])
|
||||
:in $ ?c
|
||||
:where [?vu :vendor-usage/client ?c]
|
||||
[?vu :vendor-usage/count ?count]
|
||||
[(>= ?vu 0)]
|
||||
[?vu :vendor-usage/vendor ?v]
|
||||
(not [?v :vendor/hidden true])]
|
||||
(d/db conn)
|
||||
client)
|
||||
(map (fn [[v]]
|
||||
[(-> v :vendor/name)
|
||||
(-> v :vendor/address :address/street1)
|
||||
(-> v :vendor/address :address/city)
|
||||
(-> v :vendor/address :address/state)
|
||||
(-> v :vendor/address :address/zip)
|
||||
(-> v (vendor/terms-for-client-id client) )
|
||||
(-> v (vendor/account-for-client-id client) (accounts/clientize client) :account/name)
|
||||
(-> v (vendor/account-for-client-id client) :account/numeric-code)
|
||||
]
|
||||
))
|
||||
(into [["Vendor Name" "Address" "City" "State" "Zip" "Terms" "Account" "Account Code"]]))]
|
||||
{:body
|
||||
(into (list)
|
||||
data)})))
|
||||
|
||||
(defn export-ledger [{:keys [identity query-params]}]
|
||||
(let [start-date (or (some-> (query-params "start-date")
|
||||
(atime/parse atime/iso-date))
|
||||
(time/plus (time/now) (time/days -120)))]
|
||||
(log/info "exporting for " (query-params "client-code") "starting" start-date)
|
||||
(assert-admin identity)
|
||||
(statsd/time! [(str "export.time") {:tags #{(client-tag query-params)
|
||||
"export:ledger2"}}]
|
||||
(let [results (->> (d/q '[:find (pull ?e [:db/id
|
||||
:journal-entry/external-id
|
||||
:journal-entry/cleared
|
||||
:journal-entry/alternate-description
|
||||
:journal-entry/date
|
||||
:journal-entry/note
|
||||
:journal-entry/amount
|
||||
:journal-entry/source
|
||||
:journal-entry/cleared-against
|
||||
:journal-entry/original-entity
|
||||
{:journal-entry/client [:client/name :client/code :db/id]
|
||||
:journal-entry/vendor [:vendor/name :db/id]
|
||||
:journal-entry/line-items
|
||||
[:db/id
|
||||
:journal-entry-line/location
|
||||
:journal-entry-line/debit
|
||||
:journal-entry-line/credit
|
||||
{:journal-entry-line/account
|
||||
[:bank-account/include-in-reports
|
||||
:bank-account/bank-name
|
||||
:bank-account/numeric-code
|
||||
:bank-account/code
|
||||
:bank-account/visible
|
||||
:bank-account/name
|
||||
:bank-account/number
|
||||
:account/code
|
||||
:account/name
|
||||
:account/numeric-code
|
||||
:account/location
|
||||
{:account/type [:db/ident :db/id]}
|
||||
{:bank-account/type [:db/ident :db/id]}]}]}])
|
||||
:in $ ?c ?start-date
|
||||
:where [?e :journal-entry/client ?c]
|
||||
[?e :journal-entry/date ?date]
|
||||
[(>= ?date ?start-date)]]
|
||||
(d/db conn)
|
||||
[:client/code (query-params "client-code")]
|
||||
(coerce/to-date start-date)))
|
||||
tf-result (transduce (comp
|
||||
(map first)
|
||||
(filter (fn [je]
|
||||
(every?
|
||||
(fn [jel]
|
||||
(let [include-in-reports (-> jel :journal-entry-line/account :bank-account/include-in-reports)]
|
||||
(or (nil? include-in-reports)
|
||||
(true? include-in-reports))))
|
||||
(:journal-entry/line-items je))))
|
||||
(map <-graphql))
|
||||
conj
|
||||
(list)
|
||||
results)]
|
||||
{:body
|
||||
tf-result}))))
|
||||
|
||||
(defn export-accounts [{:keys [query-params identity]}]
|
||||
(assert-admin identity)
|
||||
(statsd/time! [(str "export.time") {:tags #{(client-tag query-params)
|
||||
"export:accounts"}}]
|
||||
(let [client-id (d-clients/code->id (query-params "client-code"))
|
||||
query [[:all-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)}))]
|
||||
|
||||
{:body
|
||||
(list (transduce
|
||||
(comp
|
||||
(filter (fn [a]
|
||||
(let [overriden-clients (set (map (comp :id :client) (:client-overrides a)))]
|
||||
(or (nil? (:applicability a))
|
||||
(= :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
|
||||
(list)
|
||||
(:all-accounts (:data all-accounts))))})))
|
||||
|
||||
(defn export-transactions2 [{:keys [query-params identity]}]
|
||||
(assert-admin identity)
|
||||
(statsd/time! [(str "export.time") {:tags #{(client-tag query-params)
|
||||
"export:transactions2"}}]
|
||||
{:body (let [db (d/db conn)]
|
||||
(->>
|
||||
(d/query {:query {:find ['?e]
|
||||
:in ['$ '?client-code]
|
||||
:where ['[?e :transaction/client ?client-code]]}
|
||||
:args [db [:client/code (query-params "client-code")]]})
|
||||
(map first)
|
||||
(map (fn [e]
|
||||
(let [e (d/entity db e)
|
||||
client (:transaction/client e)
|
||||
bank-account (:transaction/bank-account e)]
|
||||
{:id (:db/id e)
|
||||
:date (:transaction/date e)
|
||||
:post_date (:transaction/post-date e)
|
||||
:client { :code (:client/code client)
|
||||
:id (:db/id client)
|
||||
:name (:client/name client)}
|
||||
:amount (:transaction/amount e)
|
||||
:description_original (:transaction/description-original e)
|
||||
:approval_status (:transaction/approval-status e)
|
||||
:bank_account {:name (:bank-account/name bank-account)
|
||||
:code (:bank-account/code bank-account)
|
||||
:id (:db/id bank-account)}})))))}))
|
||||
|
||||
(defn export-transactions [{:keys [query-params identity]}]
|
||||
(assert-admin identity)
|
||||
(statsd/time! [(str "export.time") {:tags #{(client-tag query-params)
|
||||
"export:transactions"}}]
|
||||
(let [[transactions] (d-transactions/get-graphql {:client-code (query-params "client-code")
|
||||
#_#_:original-id (Integer/parseInt (query-params "original"))
|
||||
:count Integer/MAX_VALUE})]
|
||||
|
||||
|
||||
{:body (map
|
||||
(comp ->graphql
|
||||
(fn [i]
|
||||
(cond-> i
|
||||
true (update :transaction/date to-date)
|
||||
true (update :transaction/post-date to-date)
|
||||
(:transaction/payment i) (update-in [:transaction/payment :payment/date] to-date)
|
||||
(:transaction/expected-deposit i) (update-in [:transaction/expected-deposit :expected-deposit/date] to-date))))
|
||||
transactions)})))
|
||||
|
||||
(defn export-raw [{:keys [query-params identity]}]
|
||||
(assert-admin identity)
|
||||
(log/info "Executing raw query " (get query-params "query" ))
|
||||
(statsd/time! [(str "export.time") {:tags #{"export:raw"}}]
|
||||
{:body
|
||||
(into (list) (apply d/q (read-string (get query-params "query" )) (into [(d/db conn)] (read-string (get query-params "args" "[]")))))}))
|
||||
|
||||
|
||||
(def routes2 {"api/" {"sales/" {"aggregated/" {#"export/?" {:get :aggregated-sales-export}}
|
||||
#"export/?" {:get :export-sales}}
|
||||
"invoices/" {#"export/?" {:get :export-invoices}}
|
||||
"payments/" {#"export/?" {:get :export-payments}}
|
||||
"expected-deposit/" {#"export/?" {:get :export-expected-deposits}}
|
||||
"clients/" {#"export/?" {:get :export-clients}}
|
||||
"vendors/" {#"export/?" {:get :export-vendors}
|
||||
"/company" {#"export/?" {:get :export-company-vendors}}}
|
||||
"ledger/" {#"export/?" {:get :export-ledger}}
|
||||
"accounts/" {#"export/?" {:get :export-accounts}}
|
||||
"transactions/" {#"export/?" {:get :export-transactions}
|
||||
#"export2/?" {:get :export-transactions2}}
|
||||
#"raw/?" {:get :export-raw}}})
|
||||
|
||||
(def match->handler {:aggregated-sales-export (wrap-csv-response aggregated-sales-export)
|
||||
:export-invoices (-> export-invoices wrap-json-response wrap-secure )
|
||||
:export-payments (-> export-payments wrap-json-response wrap-secure)
|
||||
:export-sales (-> export-sales wrap-json-response wrap-secure)
|
||||
:export-expected-deposits (-> export-expected-deposits wrap-json-response wrap-secure)
|
||||
:export-clients (-> export-clients wrap-json-response wrap-secure)
|
||||
:export-vendors (-> export-vendors wrap-json-response wrap-secure)
|
||||
:export-company-vendors (-> export-company-vendors wrap-csv-response wrap-secure)
|
||||
:export-ledger (-> export-ledger wrap-json-response wrap-secure)
|
||||
:export-accounts (-> export-accounts wrap-json-response wrap-secure)
|
||||
:export-transactions (-> export-transactions wrap-json-response wrap-secure)
|
||||
:export-transactions2 (-> export-transactions2 wrap-json-response wrap-secure)
|
||||
:export-raw (-> export-raw wrap-json-response wrap-secure)})
|
||||
|
||||
@@ -1,23 +1,30 @@
|
||||
(ns auto-ap.routes.ezcater
|
||||
(:require
|
||||
[clojure.tools.logging :as log]
|
||||
[compojure.core :refer [context defroutes GET POST wrap-routes]]
|
||||
[ring.middleware.json :refer [wrap-json-params]]
|
||||
[auto-ap.ezcater.core :as e]
|
||||
[ring.util.request :refer [body-string]]))
|
||||
[auto-ap.logging :as alog]
|
||||
[ring.middleware.json :refer [wrap-json-params]]))
|
||||
|
||||
(defroutes routes
|
||||
(wrap-routes
|
||||
(context "/ezcater" []
|
||||
(GET "/event" request
|
||||
(log/info (str "GET EVENT " (body-string request) request))
|
||||
{:status 200
|
||||
:headers {"Content-Type" "application/json"}
|
||||
:body "{}"})
|
||||
(POST "/event" request
|
||||
(log/info (str "POST EVENT " (body-string request) request))
|
||||
(e/import-order (:json-params request))
|
||||
{:status 200
|
||||
:headers {"Content-Type" "application/json"}
|
||||
:body "{}"}))
|
||||
wrap-json-params))
|
||||
(defn handle-ezcater [{:keys [request-method json-params] :as r}]
|
||||
(cond
|
||||
(= :get request-method)
|
||||
{:status 200
|
||||
:headers {"Content-Type" "application/json"}
|
||||
:body "{}"}
|
||||
|
||||
(= :post request-method)
|
||||
(do
|
||||
(alog/info ::ezcater-request
|
||||
:json-params json-params)
|
||||
(e/import-order json-params)
|
||||
{:status 200
|
||||
:headers {"Content-Type" "application/json"}
|
||||
:body "{}"})
|
||||
|
||||
:else
|
||||
{:status 404}))
|
||||
|
||||
|
||||
|
||||
(def routes {"api/" {"ezcater/" {#"event/?" :ezcater-event}}})
|
||||
(def match->handler {:ezcater-event (-> handle-ezcater
|
||||
wrap-json-params)})
|
||||
|
||||
@@ -4,8 +4,6 @@
|
||||
[auto-ap.logging :refer [warn-event]]
|
||||
[buddy.auth :refer [throw-unauthorized]]
|
||||
[clojure.edn :as edn]
|
||||
[compojure.core :refer [GET POST context defroutes
|
||||
wrap-routes]]
|
||||
[clojure.tools.logging :as log]))
|
||||
(defn handle-graphql [{:keys [request-method query-params] :as r}]
|
||||
(when (= "none" (:user/role (:identity r)))
|
||||
@@ -39,9 +37,5 @@
|
||||
:headers {"Content-Type" "application/edn"}}))))))
|
||||
|
||||
|
||||
(defroutes routes
|
||||
(wrap-routes
|
||||
(context "/graphql" []
|
||||
(GET "/" x (handle-graphql x))
|
||||
(POST "/" x (handle-graphql x)))
|
||||
wrap-secure))
|
||||
(def routes {"api/" {#"graphql/?" :graphql}})
|
||||
(def match->handler {:graphql (wrap-secure handle-graphql)})
|
||||
|
||||
19
src/clj/auto_ap/routes/health.clj
Normal file
19
src/clj/auto_ap/routes/health.clj
Normal file
@@ -0,0 +1,19 @@
|
||||
(ns auto-ap.routes.health
|
||||
(:require [mount.core :as mount]))
|
||||
|
||||
(def running? (atom false))
|
||||
|
||||
#_{:clj-kondo/ignore [:clojure-lsp/unused-public-var]}
|
||||
(mount/defstate manage-running?
|
||||
:start (reset! running? true)
|
||||
:stop (reset! running? false))
|
||||
|
||||
(defn health-check [request]
|
||||
(if @running?
|
||||
{:status 200
|
||||
:body "Ok"}
|
||||
{:status 503
|
||||
:body "Application shut down"}))
|
||||
|
||||
(def routes {"api/" {"health-check" :health}})
|
||||
(def match->handler {:health health-check})
|
||||
@@ -18,7 +18,6 @@
|
||||
[clojure.java.io :as io]
|
||||
[clojure.string :as str]
|
||||
[clojure.tools.logging :as log]
|
||||
[compojure.core :refer [context defroutes POST wrap-routes]]
|
||||
[config.core :refer [env]]
|
||||
[datomic.api :as d]
|
||||
[digest]
|
||||
@@ -385,142 +384,147 @@
|
||||
rows)]
|
||||
(transact-with-ledger txes nil)))
|
||||
|
||||
(defroutes routes
|
||||
(wrap-routes
|
||||
(context "/" []
|
||||
(context "/transactions" []
|
||||
(POST "/batch-upload"
|
||||
{{:keys [data]} :edn-params user :identity}
|
||||
(assert-admin user)
|
||||
(try
|
||||
(let [stats (manual/import-batch (manual/tabulate-data data) (:user/name user))]
|
||||
{:status 200
|
||||
:body (pr-str stats)
|
||||
:headers {"Content-Type" "application/edn"}})
|
||||
(catch Exception e
|
||||
(log/error e)
|
||||
{:status 500
|
||||
:body (pr-str {:message (.getMessage e)
|
||||
:error (.toString e)
|
||||
:data (ex-data e)})
|
||||
:headers {"Content-Type" "application/edn"}}))))
|
||||
(defn batch-upload-transactions [{{:keys [data]} :edn-params user :identity}]
|
||||
(assert-admin user)
|
||||
(try
|
||||
(let [stats (manual/import-batch (manual/tabulate-data data) (:user/name user))]
|
||||
{:status 200
|
||||
:body (pr-str stats)
|
||||
:headers {"Content-Type" "application/edn"}})
|
||||
(catch Exception e
|
||||
(log/error e)
|
||||
{:status 500
|
||||
:body (pr-str {:message (.getMessage e)
|
||||
:error (.toString e)
|
||||
:data (ex-data e)})
|
||||
:headers {"Content-Type" "application/edn"}})))
|
||||
|
||||
(context "/invoices" []
|
||||
(POST "/upload"
|
||||
{{files :file
|
||||
files-2 "file"
|
||||
client :client
|
||||
client-2 "client"
|
||||
location :location
|
||||
location-2 "location"
|
||||
vendor :vendor
|
||||
vendor-2 "vendor"} :params
|
||||
user :identity}
|
||||
(let [files (or files files-2)
|
||||
client (or client client-2)
|
||||
location (or location location-2)
|
||||
vendor (some-> (or vendor vendor-2)
|
||||
(Long/parseLong))
|
||||
{:keys [filename tempfile]} files]
|
||||
(lc/with-context {:parsing-file filename}
|
||||
(log/info tempfile)
|
||||
(try
|
||||
(let [extension (last (str/split (.getName (io/file filename)) #"\."))
|
||||
s3-location (str "invoice-files/" (str (UUID/randomUUID)) "." extension)
|
||||
_ (s3/put-object (:data-bucket env)
|
||||
s3-location
|
||||
(io/input-stream tempfile)
|
||||
{:content-type (if (= "csv" extension)
|
||||
"text/csv"
|
||||
"application/pdf")
|
||||
:content-length (.length tempfile)})
|
||||
imports (->> (parse/parse-file (.getPath tempfile) filename)
|
||||
(map #(assoc %
|
||||
:client-override client
|
||||
:location-override location
|
||||
:vendor-override vendor
|
||||
:source-url (str "http://" (:data-bucket env)
|
||||
".s3-website-us-east-1.amazonaws.com/"
|
||||
s3-location))))]
|
||||
(import-uploaded-invoice user imports))
|
||||
{:status 200
|
||||
:body (pr-str {})
|
||||
:headers {"Content-Type" "application/edn"}}
|
||||
(catch Exception e
|
||||
(log/warn e)
|
||||
{:status 400
|
||||
:body (pr-str {:message (.getMessage e)
|
||||
:error (.toString e)
|
||||
:data (ex-data e)})
|
||||
:headers {"Content-Type" "application/edn"}})))))
|
||||
(defn upload-invoices [{{files :file
|
||||
files-2 "file"
|
||||
client :client
|
||||
client-2 "client"
|
||||
location :location
|
||||
location-2 "location"
|
||||
vendor :vendor
|
||||
vendor-2 "vendor"} :params
|
||||
user :identity}]
|
||||
(let [files (or files files-2)
|
||||
client (or client client-2)
|
||||
location (or location location-2)
|
||||
vendor (some-> (or vendor vendor-2)
|
||||
(Long/parseLong))
|
||||
{:keys [filename tempfile]} files]
|
||||
(lc/with-context {:parsing-file filename}
|
||||
(log/info tempfile)
|
||||
(try
|
||||
(let [extension (last (str/split (.getName (io/file filename)) #"\."))
|
||||
s3-location (str "invoice-files/" (str (UUID/randomUUID)) "." extension)
|
||||
_ (s3/put-object (:data-bucket env)
|
||||
s3-location
|
||||
(io/input-stream tempfile)
|
||||
{:content-type (if (= "csv" extension)
|
||||
"text/csv"
|
||||
"application/pdf")
|
||||
:content-length (.length tempfile)})
|
||||
imports (->> (parse/parse-file (.getPath tempfile) filename)
|
||||
(map #(assoc %
|
||||
:client-override client
|
||||
:location-override location
|
||||
:vendor-override vendor
|
||||
:source-url (str "http://" (:data-bucket env)
|
||||
".s3-website-us-east-1.amazonaws.com/"
|
||||
s3-location))))]
|
||||
(import-uploaded-invoice user imports))
|
||||
{:status 200
|
||||
:body (pr-str {})
|
||||
:headers {"Content-Type" "application/edn"}}
|
||||
(catch Exception e
|
||||
(log/warn e)
|
||||
{:status 400
|
||||
:body (pr-str {:message (.getMessage e)
|
||||
:error (.toString e)
|
||||
:data (ex-data e)})
|
||||
:headers {"Content-Type" "application/edn"}})))))
|
||||
|
||||
(POST "/upload-integreat"
|
||||
{{:keys [excel-rows]} :edn-params user :identity}
|
||||
(assert-admin user)
|
||||
(let [parsed-invoice-rows (parse-invoice-rows excel-rows)
|
||||
existing-rows (set (d-invoices/get-existing-set))
|
||||
grouped-rows (group-by
|
||||
(fn [i]
|
||||
(cond (seq (:errors i))
|
||||
:error
|
||||
(defn bulk-upload-invoices [{{:keys [excel-rows]} :edn-params user :identity}]
|
||||
(assert-admin user)
|
||||
(let [parsed-invoice-rows (parse-invoice-rows excel-rows)
|
||||
existing-rows (set (d-invoices/get-existing-set))
|
||||
grouped-rows (group-by
|
||||
(fn [i]
|
||||
(cond (seq (:errors i))
|
||||
:error
|
||||
|
||||
(existing-rows [(:vendor-id i) (:client-id i) (:invoice-number i)])
|
||||
:exists
|
||||
(existing-rows [(:vendor-id i) (:client-id i) (:invoice-number i)])
|
||||
:exists
|
||||
|
||||
:else
|
||||
:new))
|
||||
parsed-invoice-rows)
|
||||
vendors-not-found (->> parsed-invoice-rows
|
||||
(filter #(and (nil? (:vendor-id %))
|
||||
(not= "Cash" (:check %))))
|
||||
(map :vendor-name)
|
||||
set)
|
||||
_ (transact-with-ledger (invoice-rows->transaction (:new grouped-rows)
|
||||
user)
|
||||
user)]
|
||||
{:status 200
|
||||
:body (pr-str {:imported (count (:new grouped-rows))
|
||||
:already-imported (count (:exists grouped-rows))
|
||||
:vendors-not-found vendors-not-found
|
||||
:errors (map #(dissoc % :date) (:error grouped-rows))})
|
||||
:headers {"Content-Type" "application/edn"}})))
|
||||
(POST "/transactions/cleared-against"
|
||||
{{files :file
|
||||
files-2 "file"} :params
|
||||
user :identity}
|
||||
(let [files (or files files-2)
|
||||
{:keys [tempfile]} files]
|
||||
(assert-admin user)
|
||||
(try
|
||||
(import-transactions-cleared-against (.getPath tempfile))
|
||||
{:status 200
|
||||
:body (pr-str {})
|
||||
:headers {"Content-Type" "application/edn"}}
|
||||
(catch Exception e
|
||||
(log/error e)
|
||||
{:status 500
|
||||
:body (pr-str {:message (.getMessage e)
|
||||
:error (.toString e)
|
||||
:data (ex-data e)})
|
||||
:headers {"Content-Type" "application/edn"}}))))
|
||||
(wrap-json-response (POST "/account-overrides"
|
||||
{{files :file
|
||||
files-2 "file"
|
||||
client :client
|
||||
client-2 "client"} :params
|
||||
user :identity}
|
||||
(let [files (or files files-2)
|
||||
client (or client client-2)
|
||||
{:keys [tempfile]} files]
|
||||
(assert-admin user)
|
||||
(try
|
||||
{:status 200
|
||||
:body (import-account-overrides client (.getPath tempfile))
|
||||
:headers {"Content-Type" "application/json"}}
|
||||
(catch Exception e
|
||||
(log/error e)
|
||||
{:status 500
|
||||
:body {:message (.getMessage e)
|
||||
:data (ex-data e)}
|
||||
:headers {"Content-Type" "application/json"}}))))))
|
||||
wrap-secure))
|
||||
:else
|
||||
:new))
|
||||
parsed-invoice-rows)
|
||||
vendors-not-found (->> parsed-invoice-rows
|
||||
(filter #(and (nil? (:vendor-id %))
|
||||
(not= "Cash" (:check %))))
|
||||
(map :vendor-name)
|
||||
set)
|
||||
_ (transact-with-ledger (invoice-rows->transaction (:new grouped-rows)
|
||||
user)
|
||||
user)]
|
||||
{:status 200
|
||||
:body (pr-str {:imported (count (:new grouped-rows))
|
||||
:already-imported (count (:exists grouped-rows))
|
||||
:vendors-not-found vendors-not-found
|
||||
:errors (map #(dissoc % :date) (:error grouped-rows))})
|
||||
:headers {"Content-Type" "application/edn"}}))
|
||||
|
||||
(defn cleared-against [{{files :file
|
||||
files-2 "file"} :params
|
||||
user :identity}]
|
||||
(let [files (or files files-2)
|
||||
{:keys [tempfile]} files]
|
||||
(assert-admin user)
|
||||
(try
|
||||
(import-transactions-cleared-against (.getPath tempfile))
|
||||
{:status 200
|
||||
:body (pr-str {})
|
||||
:headers {"Content-Type" "application/edn"}}
|
||||
(catch Exception e
|
||||
(log/error e)
|
||||
{:status 500
|
||||
:body (pr-str {:message (.getMessage e)
|
||||
:error (.toString e)
|
||||
:data (ex-data e)})
|
||||
:headers {"Content-Type" "application/edn"}}))))
|
||||
|
||||
|
||||
|
||||
(defn bulk-account-overrides [{{files :file
|
||||
files-2 "file"
|
||||
client :client
|
||||
client-2 "client"} :params
|
||||
user :identity}]
|
||||
(let [files (or files files-2)
|
||||
client (or client client-2)
|
||||
{:keys [tempfile]} files]
|
||||
(assert-admin user)
|
||||
(try
|
||||
{:status 200
|
||||
:body (import-account-overrides client (.getPath tempfile))
|
||||
:headers {"Content-Type" "application/json"}}
|
||||
(catch Exception e
|
||||
(log/error e)
|
||||
{:status 500
|
||||
:body {:message (.getMessage e)
|
||||
:data (ex-data e)}
|
||||
:headers {"Content-Type" "application/json"}}))))
|
||||
|
||||
(def routes {"api/" {"transactions/" {:post {#"batch-upload/?" :batch-upload-transactions
|
||||
#"cleared-against/?" :cleared-against}}
|
||||
"invoices/" {:post {#"upload/?" :upload-invoices
|
||||
#"upload-integreat/?" :bulk-upload-invoices}}
|
||||
:post {#"account-overrides/?" :bulk-account-overrides}}})
|
||||
|
||||
(def match->handler {:batch-upload-transactions (wrap-secure batch-upload-transactions)
|
||||
:upload-invoices (wrap-secure upload-invoices)
|
||||
:bulk-upload-invoices (wrap-secure bulk-upload-invoices)
|
||||
:cleared-against (wrap-secure cleared-against)
|
||||
:bulk-account-overrides (wrap-secure (wrap-json-response bulk-account-overrides))})
|
||||
|
||||
@@ -1,22 +1,21 @@
|
||||
(ns auto-ap.routes.queries
|
||||
(:require [amazonica.aws.s3 :as s3]
|
||||
[auto-ap.datomic :refer [conn]]
|
||||
[auto-ap.graphql.utils :refer [assert-admin]]
|
||||
[clojure.data.csv :as csv]
|
||||
[clojure.java.io :as io]
|
||||
[clojure.string :as str]
|
||||
[clojure.tools.logging :as log]
|
||||
[com.unbounce.dogstatsd.core :as statsd]
|
||||
[compojure.core
|
||||
:refer
|
||||
[context defroutes GET POST PUT routes wrap-routes]]
|
||||
[config.core :refer [env]]
|
||||
[clojure.edn :as edn]
|
||||
[datomic.api :as d]
|
||||
[ring.middleware.json :refer [wrap-json-response]]
|
||||
[ring.util.request :refer [body-string]]
|
||||
[unilog.context :as lc])
|
||||
(:import java.util.UUID))
|
||||
(:require
|
||||
[amazonica.aws.s3 :as s3]
|
||||
[auto-ap.datomic :refer [conn]]
|
||||
[auto-ap.graphql.utils :refer [assert-admin]]
|
||||
[clojure.data.csv :as csv]
|
||||
[clojure.edn :as edn]
|
||||
[clojure.java.io :as io]
|
||||
[clojure.string :as str]
|
||||
[clojure.tools.logging :as log]
|
||||
[com.unbounce.dogstatsd.core :as statsd]
|
||||
[config.core :refer [env]]
|
||||
[datomic.api :as d]
|
||||
[ring.middleware.json :refer [wrap-json-response]]
|
||||
[ring.util.request :refer [body-string]]
|
||||
[unilog.context :as lc])
|
||||
(:import
|
||||
(java.util UUID)))
|
||||
|
||||
(defn wrap-csv-response [handler]
|
||||
(fn [request]
|
||||
@@ -62,64 +61,77 @@
|
||||
:csv-results-url (str "/api/queries/" guid "/results/csv")
|
||||
:json-results-url (str "/api/queries/" guid "/results/json")}}))
|
||||
|
||||
(def json-routes
|
||||
(context "/queries" []
|
||||
(POST "/" {:keys [query-params identity] :as request}
|
||||
(assert-admin identity)
|
||||
(log/info "Note" (query-params "note"))
|
||||
(put-query (str (UUID/randomUUID)) (body-string request) (query-params "note")))
|
||||
(PUT "/:query-id" {:keys [query-params identity params] :as request}
|
||||
(assert-admin identity)
|
||||
(log/info "Note" (query-params "note"))
|
||||
(put-query (:query-id params) (body-string request) (query-params "note")))
|
||||
(GET "/:query-id" {:keys [identity params]}
|
||||
(assert-admin identity)
|
||||
(let [{:keys [query-id]} params
|
||||
obj (s3/get-object :bucket-name (:data-bucket env)
|
||||
:key (str "queries/" query-id))
|
||||
query-string (str (slurp (:object-content obj)))]
|
||||
(log/info obj)
|
||||
{:body {:query query-string
|
||||
:note (:note (:user-metadata (:object-metadata obj)))
|
||||
:id query-id
|
||||
:csv-results-url (str "/api/queries/" query-id "/results/csv")
|
||||
:json-results-url (str "/api/queries/" query-id "/results/json")}}))
|
||||
|
||||
|
||||
(GET "/" {:keys [identity]}
|
||||
(assert-admin identity)
|
||||
(let [obj (s3/list-objects :bucket-name (:data-bucket env)
|
||||
:prefix (str "queries/"))]
|
||||
(log/info obj)
|
||||
{:body (->> (:object-summaries obj)
|
||||
(map (fn [o]
|
||||
{:last-modified (.toString (:last-modified o))
|
||||
:key (str/replace (:key o) #"^queries\/" "")})))}))
|
||||
|
||||
(GET "/:query-id/results/json" {:keys [query-params params]}
|
||||
(statsd/time! [(str "export.query.time") {:tags #{(str "query:" (:query-id params))}}]
|
||||
{:body (execute-query query-params params)}))))
|
||||
|
||||
|
||||
(def raw-routes
|
||||
(context "/queries" []
|
||||
(GET "/:query-id/raw" {:keys [identity params]}
|
||||
(assert-admin identity)
|
||||
(let [{:keys [query-id]} params
|
||||
obj (s3/get-object :bucket-name (:data-bucket env)
|
||||
:key (str "queries/" query-id))
|
||||
query-string (str (slurp (:object-content obj)))]
|
||||
(log/info obj)
|
||||
{:body query-string}))))
|
||||
(defn get-queries [{:keys [identity]}]
|
||||
(assert-admin identity)
|
||||
(let [obj (s3/list-objects :bucket-name (:data-bucket env)
|
||||
:prefix (str "queries/"))]
|
||||
(log/info obj)
|
||||
{:body (->> (:object-summaries obj)
|
||||
(map (fn [o]
|
||||
{:last-modified (.toString (:last-modified o))
|
||||
:key (str/replace (:key o) #"^queries\/" "")})))}))
|
||||
|
||||
(defn create-query [{:keys [query-params identity] :as request}]
|
||||
(assert-admin identity)
|
||||
(log/info "Note" (query-params "note"))
|
||||
(put-query (str (UUID/randomUUID)) (body-string request) (query-params "note")))
|
||||
|
||||
(defn get-query [{:keys [identity params]} ]
|
||||
(assert-admin identity)
|
||||
(let [{:keys [query-id]} params
|
||||
obj (s3/get-object :bucket-name (:data-bucket env)
|
||||
:key (str "queries/" query-id))
|
||||
query-string (str (slurp (:object-content obj)))]
|
||||
(log/info obj)
|
||||
{:body {:query query-string
|
||||
:note (:note (:user-metadata (:object-metadata obj)))
|
||||
:id query-id
|
||||
:csv-results-url (str "/api/queries/" query-id "/results/csv")
|
||||
:json-results-url (str "/api/queries/" query-id "/results/json")}}))
|
||||
|
||||
(defn update-query [{:keys [query-params identity params] :as request} ]
|
||||
(assert-admin identity)
|
||||
(log/info "Note" (query-params "note"))
|
||||
(put-query (:query-id params) (body-string request) (query-params "note")))
|
||||
|
||||
(defn results-json-query [{:keys [query-params params]}]
|
||||
(statsd/time! [(str "export.query.time") {:tags #{(str "query:" (:query-id params))}}]
|
||||
{:body (execute-query query-params params)}))
|
||||
|
||||
(defn raw-query [{:keys [identity params]}]
|
||||
(assert-admin identity)
|
||||
(let [{:keys [query-id]} params
|
||||
obj (s3/get-object :bucket-name (:data-bucket env)
|
||||
:key (str "queries/" query-id))
|
||||
query-string (str (slurp (:object-content obj)))]
|
||||
(log/info obj)
|
||||
{:body query-string}))
|
||||
|
||||
(defn results-csv-query [{:keys [query-params params]}]
|
||||
(statsd/time! [(str "export.query.time") {:tags #{(str "query:" (:query-id params))}}]
|
||||
{:body (execute-query query-params params)}))
|
||||
|
||||
(def routes2 {"api/" {#"queries/?" {[:query-id "/raw"] {:get :raw-query}
|
||||
[:query-id "/results/csv"] {:get :results-csv-query}
|
||||
[:query-id "/results/json"] {:get :results-json-query}
|
||||
[:query-id] {:get :get-query
|
||||
:put :update-query}
|
||||
:get :get-queries
|
||||
:post :create-query}}})
|
||||
|
||||
(def match->handler {:get-queries get-queries
|
||||
:create-query create-query
|
||||
:raw-query raw-query
|
||||
:get-query (-> get-query
|
||||
wrap-json-response)
|
||||
:update-query (-> update-query
|
||||
wrap-json-response)
|
||||
|
||||
:results-json-query (-> results-json-query
|
||||
wrap-json-response)
|
||||
:results-csv-query (-> results-csv-query
|
||||
wrap-csv-response)})
|
||||
|
||||
|
||||
(def csv-routes
|
||||
(context "/queries" []
|
||||
(GET "/:query-id/results/csv" {:keys [query-params params]}
|
||||
(statsd/time! [(str "export.query.time") {:tags #{(str "query:" (:query-id params))}}]
|
||||
{:body (execute-query query-params params)}))))
|
||||
(defroutes query2-routes
|
||||
(routes
|
||||
raw-routes
|
||||
(wrap-routes json-routes
|
||||
wrap-json-response)
|
||||
(wrap-routes csv-routes wrap-csv-response)))
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
(ns auto-ap.routes.utils
|
||||
(:require [buddy.auth :refer [authenticated?]]))
|
||||
(:require
|
||||
[auto-ap.graphql.utils :refer [is-admin?]]
|
||||
[buddy.auth :refer [authenticated?]]
|
||||
[auto-ap.logging :as alog]))
|
||||
|
||||
(defn wrap-secure [handler]
|
||||
(fn [request]
|
||||
@@ -7,3 +10,20 @@
|
||||
(handler request)
|
||||
{:status 401
|
||||
:body "not authenticated"})))
|
||||
|
||||
(defn wrap-admin [handler]
|
||||
(fn [request]
|
||||
(if (is-admin? (:identity request))
|
||||
(handler request)
|
||||
(do
|
||||
(alog/warn ::unauthenticated)
|
||||
{:status 302
|
||||
:headers "/login"}))))
|
||||
|
||||
(defn wrap-client-redirect-unauthenticated [handler]
|
||||
(fn [request]
|
||||
(let [response (handler request)]
|
||||
(println )
|
||||
(if (= 401 (get response :status))
|
||||
(assoc-in response [:headers "hx-redirect"] "/login/")
|
||||
response))))
|
||||
|
||||
@@ -6,99 +6,113 @@
|
||||
[auto-ap.routes.utils :refer [wrap-secure]]
|
||||
[auto-ap.yodlee.core2 :as yodlee]
|
||||
[clojure.tools.logging :as log]
|
||||
[compojure.core :refer [context defroutes GET POST wrap-routes]]
|
||||
[config.core :refer [env]]
|
||||
[datomic.api :as d]))
|
||||
|
||||
(defroutes routes
|
||||
(wrap-routes
|
||||
(context "/yodlee2" []
|
||||
(GET "/fastlink" {:keys [query-params identity]}
|
||||
(assert-can-see-client identity (d/pull (d/db conn) [:db/id] [:client/code (get query-params "client")]))
|
||||
|
||||
(let [token (if-let [client-id (get query-params "client-id")]
|
||||
(-> client-id
|
||||
Long/parseLong
|
||||
d-clients/get-by-id
|
||||
:client/code
|
||||
(yodlee/get-access-token))
|
||||
(yodlee/get-access-token (get query-params "client")))]
|
||||
{:status 200
|
||||
:headers {"Content-Type" "application/edn"}
|
||||
:body (pr-str {:token token
|
||||
:url (:yodlee2-fastlink env)}) }))
|
||||
(POST "/provider-accounts/refresh/" {:keys [identity edn-params]}
|
||||
(assert-admin identity)
|
||||
(log/info "refreshing " edn-params)
|
||||
(try
|
||||
(yodlee/refresh-provider-account (-> (:client-id edn-params)
|
||||
Long/parseLong
|
||||
d-clients/get-by-id
|
||||
:client/code)
|
||||
(:provider-account-id edn-params))
|
||||
{:status 200
|
||||
:headers {"Content-Type" "application/edn"}
|
||||
:body "{}" }
|
||||
(catch Exception e
|
||||
(log/error e)
|
||||
{:status 400
|
||||
:headers {"Content-Type" "application/edn"}
|
||||
:body (pr-str {:message (.getMessage e)
|
||||
:error (.toString e)})})))
|
||||
(defn fastlink [{:keys [query-params identity]}]
|
||||
(assert-can-see-client identity (d/pull (d/db conn) [:db/id] [:client/code (get query-params "client")]))
|
||||
|
||||
(let [token (if-let [client-id (get query-params "client-id")]
|
||||
(-> client-id
|
||||
Long/parseLong
|
||||
d-clients/get-by-id
|
||||
:client/code
|
||||
(yodlee/get-access-token))
|
||||
(yodlee/get-access-token (get query-params "client")))]
|
||||
{:status 200
|
||||
:headers {"Content-Type" "application/edn"}
|
||||
:body (pr-str {:token token
|
||||
:url (:yodlee2-fastlink env)}) }))
|
||||
(defn refresh-provider-accounts [{:keys [identity edn-params]}]
|
||||
(assert-admin identity)
|
||||
(log/info "refreshing " edn-params)
|
||||
(try
|
||||
(yodlee/refresh-provider-account (-> (:client-id edn-params)
|
||||
Long/parseLong
|
||||
d-clients/get-by-id
|
||||
:client/code)
|
||||
(:provider-account-id edn-params))
|
||||
{:status 200
|
||||
:headers {"Content-Type" "application/edn"}
|
||||
:body "{}" }
|
||||
(catch Exception e
|
||||
(log/error e)
|
||||
{:status 400
|
||||
:headers {"Content-Type" "application/edn"}
|
||||
:body (pr-str {:message (.getMessage e)
|
||||
:error (.toString e)})})))
|
||||
|
||||
(GET "/provider-accounts/:client/:id" {:keys [identity]
|
||||
{:keys [client id]} :route-params}
|
||||
(assert-admin identity)
|
||||
(log/info "looking-up " client id)
|
||||
(try
|
||||
|
||||
{:status 200
|
||||
:headers {"Content-Type" "application/edn"}
|
||||
:body (pr-str (yodlee/get-provider-account-detail (-> client
|
||||
Long/parseLong
|
||||
d-clients/get-by-id
|
||||
:client/code)
|
||||
id))}
|
||||
(catch Exception e
|
||||
(log/error e)
|
||||
{:status 400
|
||||
:headers {"Content-Type" "application/edn"}
|
||||
:body (pr-str {:message (.getMessage e)
|
||||
:error (.toString e)})})))
|
||||
(POST "/provider-accounts/delete/" {:keys [edn-params identity]}
|
||||
(assert-admin identity)
|
||||
(try
|
||||
(yodlee/delete-provider-account (-> (:client-id edn-params)
|
||||
Long/parseLong
|
||||
d-clients/get-by-id
|
||||
:client/code)
|
||||
(:provider-account-id edn-params))
|
||||
{:status 200
|
||||
:headers {"Content-Type" "application/edn"}
|
||||
:body (pr-str {}) }
|
||||
(catch Exception e
|
||||
(log/error e)
|
||||
{:status 400
|
||||
:headers {"Content-Type" "application/edn"}
|
||||
:body (pr-str {:message (.getMessage e)
|
||||
:error (.toString e)})})))
|
||||
(POST "/reauthenticate/:id" {:keys [identity] {:keys [id]} :route-params
|
||||
data :edn-params}
|
||||
(assert-admin identity)
|
||||
(try
|
||||
{:status 200
|
||||
:headers {"Content-Type" "application/edn"}
|
||||
:body (pr-str (yodlee/reauthenticate-and-recache
|
||||
(-> (:client-id data)
|
||||
Long/parseLong
|
||||
d-clients/get-by-id
|
||||
:client/code)
|
||||
(Long/parseLong id)
|
||||
(dissoc data :client-id )))}
|
||||
(catch Exception e
|
||||
(log/error e)
|
||||
{:status 500
|
||||
:headers {"Content-Type" "application/edn"}
|
||||
:body (pr-str {:message (.getMessage e)
|
||||
:error (.toString e)})}))))
|
||||
wrap-secure))
|
||||
(defn get-provider-account-detail [{:keys [identity]
|
||||
{:keys [client id]} :route-params}]
|
||||
(assert-admin identity)
|
||||
(log/info "looking-up " client id)
|
||||
(try
|
||||
|
||||
{:status 200
|
||||
:headers {"Content-Type" "application/edn"}
|
||||
:body (pr-str (yodlee/get-provider-account-detail (-> client
|
||||
Long/parseLong
|
||||
d-clients/get-by-id
|
||||
:client/code)
|
||||
id))}
|
||||
(catch Exception e
|
||||
(log/error e)
|
||||
{:status 400
|
||||
:headers {"Content-Type" "application/edn"}
|
||||
:body (pr-str {:message (.getMessage e)
|
||||
:error (.toString e)})})))
|
||||
(defn reauthenticate [{:keys [identity] {:keys [id]} :route-params
|
||||
data :edn-params}]
|
||||
(assert-admin identity)
|
||||
(try
|
||||
{:status 200
|
||||
:headers {"Content-Type" "application/edn"}
|
||||
:body (pr-str (yodlee/reauthenticate-and-recache
|
||||
(-> (:client-id data)
|
||||
Long/parseLong
|
||||
d-clients/get-by-id
|
||||
:client/code)
|
||||
(Long/parseLong id)
|
||||
(dissoc data :client-id )))}
|
||||
(catch Exception e
|
||||
(log/error e)
|
||||
{:status 500
|
||||
:headers {"Content-Type" "application/edn"}
|
||||
:body (pr-str {:message (.getMessage e)
|
||||
:error (.toString e)})})))
|
||||
|
||||
(defn delete-provider-account [{:keys [edn-params identity]}]
|
||||
(assert-admin identity)
|
||||
(try
|
||||
(yodlee/delete-provider-account (-> (:client-id edn-params)
|
||||
Long/parseLong
|
||||
d-clients/get-by-id
|
||||
:client/code)
|
||||
(:provider-account-id edn-params))
|
||||
{:status 200
|
||||
:headers {"Content-Type" "application/edn"}
|
||||
:body (pr-str {}) }
|
||||
(catch Exception e
|
||||
(log/error e)
|
||||
{:status 400
|
||||
:headers {"Content-Type" "application/edn"}
|
||||
:body (pr-str {:message (.getMessage e)
|
||||
:error (.toString e)})})))
|
||||
|
||||
(defn valid-for [handler & methods]
|
||||
(let [methods (into #{} methods)]
|
||||
(fn [request]
|
||||
(if (methods (:request-method request))
|
||||
(handler request)
|
||||
{:status 404}))))
|
||||
|
||||
(def routes {"api" {"/yodlee2" {"/fastlink" :fastlink
|
||||
"/provider-accounts/refresh/" :refresh-provider-accounts
|
||||
["/provider-accounts/" :client "/" :id ] :get-provider-account-detail
|
||||
["/reauthenticate/" :id ] :reauthenticate
|
||||
"/provider-accounts/delete/" :delete-provider-account}}})
|
||||
(def match->handler {:fastlink (-> fastlink wrap-secure (valid-for :get))
|
||||
:refresh-provider-accounts (-> refresh-provider-accounts wrap-secure (valid-for :post))
|
||||
:get-provider-account-detail (-> get-provider-account-detail wrap-secure (valid-for :get))
|
||||
:reauthenticate (-> reauthenticate wrap-secure (valid-for :post))
|
||||
:delete-provider-account (-> delete-provider-account wrap-secure (valid-for :post))} )
|
||||
|
||||
Reference in New Issue
Block a user