adds the ability to export vendors.
This commit is contained in:
23
scratch-sessions/register_invoices.clj
Normal file
23
scratch-sessions/register_invoices.clj
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
(ns register-invoices)
|
||||||
|
|
||||||
|
(def totals
|
||||||
|
|
||||||
|
(into []
|
||||||
|
(d/q '[:find [(pull ?i [:db/id
|
||||||
|
:invoice/date
|
||||||
|
{:invoice/expense-accounts [:db/id
|
||||||
|
:invoice-expense-account/amount
|
||||||
|
{:invoice-expense-account/account [:db/id :account/numeric-code]}
|
||||||
|
:invoice-expense-account/location]}]) ...]
|
||||||
|
:in $
|
||||||
|
:where [?i :invoice/client [:client/code "MBD"]]
|
||||||
|
[?i :invoice/date ?d]
|
||||||
|
[(<= ?d #inst "2022-01-01T08:00:00")]]
|
||||||
|
(d/db conn))))
|
||||||
|
|
||||||
|
(clojure.data.csv/write-csv *out*
|
||||||
|
(doall (for [{:keys [:db/id :invoice/expense-accounts :invoice/date]} totals
|
||||||
|
{:keys [:invoice-expense-account/amount :invoice-expense-account/location :invoice-expense-account/account] :as g} expense-accounts
|
||||||
|
]
|
||||||
|
[id (:db/id g) (:db/id account) (atime/unparse (coerce/to-date-time date) atime/normal-date) amount (:account/numeric-code account) location]))
|
||||||
|
:separator \tab)
|
||||||
@@ -1,24 +1,27 @@
|
|||||||
(ns auto-ap.routes.exports
|
(ns auto-ap.routes.exports
|
||||||
(:require [auto-ap.datomic :refer [conn]]
|
(:require
|
||||||
|
[auto-ap.datomic :refer [conn]]
|
||||||
|
[auto-ap.datomic.accounts :as accounts]
|
||||||
[auto-ap.datomic.clients :as d-clients]
|
[auto-ap.datomic.clients :as d-clients]
|
||||||
[auto-ap.datomic.transactions :as d-transactions]
|
[auto-ap.datomic.transactions :as d-transactions]
|
||||||
[clojure.edn :refer [read-string]]
|
[auto-ap.datomic.vendors :as vendor]
|
||||||
[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 assert-can-see-client]]
|
[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]
|
[auto-ap.time :as atime]
|
||||||
|
[buddy.sign.jwt :as jwt]
|
||||||
[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]
|
||||||
[clojure.data.csv :as csv]
|
[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]]
|
[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]))
|
||||||
[com.unbounce.dogstatsd.core :as statsd]
|
|
||||||
[auto-ap.time :as atime]))
|
|
||||||
|
|
||||||
(defn wrap-csv-response [handler]
|
(defn wrap-csv-response [handler]
|
||||||
(fn [request]
|
(fn [request]
|
||||||
@@ -212,6 +215,49 @@
|
|||||||
:where [?e :vendor/name]]
|
:where [?e :vendor/name]]
|
||||||
(d/db conn))
|
(d/db conn))
|
||||||
(d/pull-many (d/db conn) d-vendors/default-read)))))
|
(d/pull-many (d/db conn) d-vendors/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]]
|
||||||
|
(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)
|
||||||
|
(.toString w))})))
|
||||||
(GET "/ledger/export" {:keys [identity query-params]}
|
(GET "/ledger/export" {:keys [identity query-params]}
|
||||||
(let [start-date (or (some-> (query-params "start-date")
|
(let [start-date (or (some-> (query-params "start-date")
|
||||||
(atime/parse atime/iso-date))
|
(atime/parse atime/iso-date))
|
||||||
|
|||||||
@@ -31,6 +31,8 @@
|
|||||||
"requires-feedback" :requires-feedback-transactions
|
"requires-feedback" :requires-feedback-transactions
|
||||||
"excluded" :excluded-transactions}
|
"excluded" :excluded-transactions}
|
||||||
"reports/" {"" :reports}
|
"reports/" {"" :reports}
|
||||||
|
"company/" {"other" :company-other
|
||||||
|
"export-vendors" :company-export-vendors}
|
||||||
"plaid" :plaid
|
"plaid" :plaid
|
||||||
"yodlee2" :yodlee2
|
"yodlee2" :yodlee2
|
||||||
"ledger/" {"" :ledger
|
"ledger/" {"" :ledger
|
||||||
|
|||||||
@@ -30,7 +30,8 @@
|
|||||||
[auto-ap.views.pages.admin.users :refer [admin-users-page]]
|
[auto-ap.views.pages.admin.users :refer [admin-users-page]]
|
||||||
[auto-ap.views.pages.admin.import-batches :refer [import-batches-page]]
|
[auto-ap.views.pages.admin.import-batches :refer [import-batches-page]]
|
||||||
[auto-ap.views.pages.company.yodlee2 :as yodlee2]
|
[auto-ap.views.pages.company.yodlee2 :as yodlee2]
|
||||||
[auto-ap.views.pages.company.plaid :as plaid]))
|
[auto-ap.views.pages.company.plaid :as plaid]
|
||||||
|
[auto-ap.views.pages.company.other :as company-other]))
|
||||||
|
|
||||||
(defmulti page (fn [active-page] active-page))
|
(defmulti page (fn [active-page] active-page))
|
||||||
(defmethod page :unpaid-invoices [_]
|
(defmethod page :unpaid-invoices [_]
|
||||||
@@ -121,6 +122,9 @@
|
|||||||
(defmethod page :yodlee2 [_]
|
(defmethod page :yodlee2 [_]
|
||||||
(yodlee2/admin-yodlee-provider-accounts-page))
|
(yodlee2/admin-yodlee-provider-accounts-page))
|
||||||
|
|
||||||
|
(defmethod page :company-other [_]
|
||||||
|
(company-other/company-other-page))
|
||||||
|
|
||||||
(defmethod page :plaid [_]
|
(defmethod page :plaid [_]
|
||||||
(plaid/plaid-page))
|
(plaid/plaid-page))
|
||||||
|
|
||||||
|
|||||||
76
src/cljs/auto_ap/views/pages/company/other.cljs
Normal file
76
src/cljs/auto_ap/views/pages/company/other.cljs
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
(ns auto-ap.views.pages.company.other
|
||||||
|
(:require
|
||||||
|
[auto-ap.subs :as subs]
|
||||||
|
[auto-ap.views.utils :refer [dispatch-event with-user]]
|
||||||
|
[auto-ap.views.components.buttons :refer [fa-icon]]
|
||||||
|
[auto-ap.views.components.layouts :refer [side-bar-layout]]
|
||||||
|
[auto-ap.views.pages.company.side-bar :refer [company-side-bar]]
|
||||||
|
[re-frame.core :as re-frame]
|
||||||
|
[reagent.core :as reagent]
|
||||||
|
[vimsical.re-frame.cofx.inject :as inject]
|
||||||
|
[auto-ap.status :as status]))
|
||||||
|
|
||||||
|
(re-frame/reg-event-fx
|
||||||
|
::ready
|
||||||
|
(fn [{:keys [db] } [_ result]]
|
||||||
|
{:db (assoc db ::export-result result)}))
|
||||||
|
|
||||||
|
(re-frame/reg-sub
|
||||||
|
::export-result
|
||||||
|
(fn [db]
|
||||||
|
(::export-result db)))
|
||||||
|
|
||||||
|
(re-frame/reg-event-fx
|
||||||
|
::export-vendors
|
||||||
|
[(re-frame/inject-cofx ::inject/sub [::subs/client]) with-user]
|
||||||
|
(fn [{:keys [db user] ::subs/keys [client]}]
|
||||||
|
{:http {:token user
|
||||||
|
:method :get
|
||||||
|
:headers {"Content-Type" "application/edn"}
|
||||||
|
:uri (str "/api/vendors/company/export?client=" (:code client))
|
||||||
|
:owns-state {:single ::export-vendors}
|
||||||
|
:on-success [::ready]}}))
|
||||||
|
|
||||||
|
(re-frame/reg-event-fx
|
||||||
|
::unmounted
|
||||||
|
(fn [{:keys [db]} _]
|
||||||
|
{:db (dissoc db ::export-result)}))
|
||||||
|
|
||||||
|
(defn company-other-content []
|
||||||
|
(let [client @(re-frame/subscribe [::subs/client])
|
||||||
|
state @(re-frame/subscribe [::status/single ::export-vendors])
|
||||||
|
export-result @(re-frame/subscribe [::export-result])]
|
||||||
|
(if client
|
||||||
|
[:div
|
||||||
|
[:h1.title "Other"]
|
||||||
|
[status/status-notification [::status/single ::export-vendors]]
|
||||||
|
|
||||||
|
|
||||||
|
[fa-icon {:icon "fa-external-link"
|
||||||
|
:class (into (status/class-for state) ["is-primary" ])
|
||||||
|
:disabled (status/disabled-for state)
|
||||||
|
:event [::export-vendors]
|
||||||
|
}
|
||||||
|
[:div
|
||||||
|
(str " Export " (:name client) " Vendors")
|
||||||
|
]]
|
||||||
|
(when export-result
|
||||||
|
[:<>
|
||||||
|
[:div
|
||||||
|
"Ready! Click "
|
||||||
|
[:a {:href (str "data:attachment/csv;charset=utf-8," (js/encodeURI export-result))
|
||||||
|
:target "_blank"
|
||||||
|
:download (str "vendors-" (:code client) ".csv")}
|
||||||
|
"here"]
|
||||||
|
" to download"]])
|
||||||
|
]
|
||||||
|
[:div "Please select a company."])))
|
||||||
|
|
||||||
|
|
||||||
|
(defn company-other-page []
|
||||||
|
(reagent/create-class
|
||||||
|
{:reagent-render (fn []
|
||||||
|
[side-bar-layout {:side-bar [company-side-bar {}]
|
||||||
|
:main [company-other-content]}])
|
||||||
|
:component-will-unmount #(re-frame/dispatch [::unmounted])}))
|
||||||
|
|
||||||
@@ -22,4 +22,8 @@
|
|||||||
[:li.menu-item
|
[:li.menu-item
|
||||||
[:a {:href (bidi/path-for routes/routes :yodlee2), :class (str "item" (active-when ap = :yodlee2))}
|
[:a {:href (bidi/path-for routes/routes :yodlee2), :class (str "item" (active-when ap = :yodlee2))}
|
||||||
[:span {:class "icon icon-saving-bank-1" :style {:font-size "25px"}}]
|
[:span {:class "icon icon-saving-bank-1" :style {:font-size "25px"}}]
|
||||||
[:span {:class "name"} "Yodlee Link"]]]]))
|
[:span {:class "name"} "Yodlee Link"]]]
|
||||||
|
[:li.menu-item
|
||||||
|
[:a {:href (bidi/path-for routes/routes :company-other), :class (str "item" (active-when ap = :company-other))}
|
||||||
|
[:span {:class "icon icon-cog-play-1" :style {:font-size "25px"}}]
|
||||||
|
[:span {:class "name"} "Other"]]]]))
|
||||||
|
|||||||
Reference in New Issue
Block a user