Adds new expense report, with ability to break down by vendor

This commit is contained in:
2024-04-19 21:48:28 -07:00
parent 706924c21c
commit 22e92c819b
12 changed files with 141 additions and 45 deletions

View File

@@ -36,6 +36,12 @@
localize
(f/unparse excel-formatter )))
(def iso-formatter (f/with-zone (f/formatter "yyyy-MM-dd") (time/time-zone-for-id "America/Los_Angeles")))
(defn iso-date [d]
(->> d
(coerce/to-date-time)
localize
(f/unparse iso-formatter )))
(defn sales-orders-in-range [db client start end]
(let [end (or end #inst "2050-01-01")]

View File

@@ -242,11 +242,26 @@
}
/* Use this selector to override the line style on a given series */
.ct-series-a .ct-bar {
/* Set the colour of this series line */
stroke: #79b52e;
fill: #79b52e;
/* Control the thikness of your lines */
stroke-width: 20px;
}
.ct-series-b .ct-bar {
stroke: #ff0303;
fill: #ff0303;
}
.ct-series-c .ct-bar {
stroke: #009cea;
fill: #009cea;
}
.ct-series-d .ct-bar {
stroke: #f48017;
fill: #f48017;
}
.ct-series-e .ct-bar {
stroke: #9c27b0;
fill: #9c27b0;
}

File diff suppressed because one or more lines are too long

View File

@@ -254,9 +254,14 @@
(comment
(auto-ap.datomic/transact-schema conn)
@(dc/transact conn [{:db/ident :sales-summary/total-unknown-processor-payments
:db/noHistory true,
:db/valueType :db.type/double
:db/cardinality :db.cardinality/one}])
(apply mark-dirty [:client/code "NGCL"] (last-n-days 12))
(mark-all-dirty 30)
(mark-all-dirty 50)
(sales-summaries)

View File

@@ -4,6 +4,7 @@
[clj-time.core :as time]
[clojure.string :as str]))
;; TODO should be able to get rid of this
(defn wrap-copy-qp-pqp [handler]
(fn [request]
(handler (assoc request :parsed-query-params (:query-params request)))))

View File

@@ -1002,7 +1002,21 @@
(clojure.pprint/pprint (let [[c [l]] (get-square-client-and-location "NGWC")]
(require 'auto-ap.time-reader)
(clojure.pprint/pprint (let [[c [l]] (get-square-client-and-location "NGHW")]
(def z @(search c l #clj-time/date-time "2024-04-10T00:00:00-08:00"
#clj-time/date-time "2024-04-13T00:00:00-08:00"))))
(->> z
(filter (fn [o]
(seq (filter (comp #{"OTHER"} :type) (:tenders o)))))
(filter #(not (:name (:source %))))
(count)
)
#_(filter (comp #{"OTHER"} :type) (mapcat :tenders z))
(get-order c l "yzmLBYVGhKXUPwGXm482GJb2VX9YY")))
)

View File

@@ -1,25 +1,23 @@
(ns auto-ap.ssr.company.reports
(:require
[amazonica.aws.s3 :as s3]
[auto-ap.datomic
:refer [add-sorter-fields
apply-pagination
apply-sort-3
conn
merge-query
pull-many
query2]]
[auto-ap.graphql.utils :refer [assert-can-see-client is-admin?]]
[auto-ap.ssr-routes :as ssr-routes]
[auto-ap.ssr.components :as com]
[auto-ap.ssr.grid-page-helper :as helper]
[auto-ap.ssr.svg :as svg]
[auto-ap.ssr.utils :refer [html-response]]
[auto-ap.time :as atime]
[bidi.bidi :as bidi]
[clojure.set :as set]
[config.core :refer [env]]
[datomic.api :as dc]))
(:require [amazonica.aws.s3 :as s3]
[auto-ap.datomic
:refer [add-sorter-fields apply-pagination apply-sort-3 conn merge-query
pull-many query2]]
[auto-ap.graphql.utils :refer [assert-can-see-client is-admin?]]
[auto-ap.routes.utils :refer [wrap-client-redirect-unauthenticated
wrap-secure]]
[auto-ap.ssr-routes :as ssr-routes]
[auto-ap.ssr.company.reports.expense :as company-expense-report]
[auto-ap.ssr.components :as com]
[auto-ap.ssr.grid-page-helper :as helper]
[auto-ap.ssr.svg :as svg]
[auto-ap.ssr.utils :refer [apply-middleware-to-all-handlers
html-response]]
[auto-ap.time :as atime]
[bidi.bidi :as bidi]
[clojure.set :as set]
[config.core :refer [env]]
[datomic.api :as dc]))
(def default-read '[:db/id :report/client [:report/created :xform clj-time.coerce/from-date] :report/url :report/name :report/creator])
@@ -132,3 +130,16 @@
{:flash? true
:delete-after-settle? true}))))
(def key->handler
(apply-middleware-to-all-handlers
(->>
(into
{:company-reports page
:company-reports-table table
:company-reports-delete delete-report}
company-expense-report/key->handler))
(fn [h]
(-> h
(wrap-secure)
(wrap-client-redirect-unauthenticated)))))

View File

@@ -270,10 +270,11 @@
:external-import-ledger)} "External Ledger Import")))))]))
(defn company-aside-nav- [_]
(defn company-aside-nav- [request]
[:ul {:class "space-y-2" :hx-boost "true"}
[:li
(menu-button- {:icon svg/vendors
:active? (= :company (:matched-route request))
:href (bidi/path-for ssr-routes/only-routes
:company)
:hx-boost true}
@@ -281,24 +282,35 @@
[:li
(menu-button- {:icon svg/report
:active? (= :company-reports (:matched-route request))
:href (bidi/path-for ssr-routes/only-routes
:company-reports)
:hx-boost true}
"Reports")]
[:li
(menu-button- {:icon svg/report
:active? (= :company-expense-report (:matched-route request))
:href (bidi/path-for ssr-routes/only-routes
:company-expense-report)
:hx-boost true}
"Expense Report")]
[:li
(menu-button- {:icon svg/bank
:active? (= :company-plaid (:matched-route request))
:href (bidi/path-for ssr-routes/only-routes
:company-plaid)
:hx-boost true}
"Plaid Link")]
[:li
(menu-button- {:icon svg/bank
:active? (= :company-yodlee (:matched-route request))
:href (bidi/path-for ssr-routes/only-routes
:company-yodlee)
:hx-boost true}
"Yodlee Link")]
[:li
(menu-button- {:icon svg/government-building
:active? (= :company-1099 (:matched-route request))
:href (bidi/path-for ssr-routes/only-routes
:company-1099)
:hx-boost true}

View File

@@ -66,9 +66,6 @@
:company-yodlee-fastlink-dialog (wrap-client-redirect-unauthenticated (wrap-secure company-yodlee/fastlink-dialog))
:company-yodlee-provider-account-refresh (wrap-client-redirect-unauthenticated (wrap-admin company-yodlee/refresh-provider-account))
:company-yodlee-provider-account-reauthenticate (wrap-client-redirect-unauthenticated (wrap-secure company-yodlee/reauthenticate))
:company-reports (wrap-client-redirect-unauthenticated (wrap-secure company-reports/page))
:company-reports-table (wrap-client-redirect-unauthenticated (wrap-secure company-reports/table))
:company-reports-delete (wrap-client-redirect-unauthenticated (wrap-admin company-reports/delete-report))
:invoice-glimpse (wrap-client-redirect-unauthenticated (wrap-admin invoice-glimpse/page))
:invoice-glimpse-upload (wrap-client-redirect-unauthenticated (wrap-admin invoice-glimpse/upload))
:invoice-glimpse-textract-invoice (wrap-client-redirect-unauthenticated (wrap-admin invoice-glimpse/textract-invoice))
@@ -83,6 +80,7 @@
:transaction-insight-explain (wrap-client-redirect-unauthenticated (wrap-admin insights/explain))
:admin-ezcater-xls (wrap-client-redirect-unauthenticated (wrap-admin ezcater-xls/page))
:search (wrap-client-redirect-unauthenticated (wrap-secure search/dialog-contents))}
(into company-reports/key->handler)
(into company-1099/key->handler)
(into invoice/key->handler)
(into import-batch/key->handler)

View File

@@ -342,8 +342,28 @@
db
[
[ (pull-attr db :db/id [:client/code "NGRV"])]
#inst "2024-03-01" #inst "2024-03-30"]))
[ (pull-attr db :db/id [:client/code "NGA1"])]
#inst "2023-01-01" #inst "2024-01-01"]))
:separator \tab)
(pull-attr (dc/db conn) :db/id [:client/code "NGRV"])
(clojure.data.csv/write-csv *out*
(let [db (dc/db conn)]
(dc/q '[:find ?d4 (sum ?a)
:in $ [?clients ?start-date ?end-date] ?v
:where
[(iol-ion.query/scan-transactions $ ?clients ?start-date ?end-date) [[?e _ ?sort-default] ...]]
[?e :transaction/date ?d]
[(iol-ion.query/excel-date ?d) ?d4]
[?e :transaction/amount ?a]
[?e :transaction/vendor ?v]]
db
[
[ (pull-attr db :db/id [:client/code "NGA1"])]
#inst "2023-01-01" #inst "2024-01-01"]
(ffirst (dc/q '[:find ?v :where [?v :vendor/name "CCP Doordash"]] db))))
:separator \tab)

View File

@@ -84,7 +84,9 @@
:post :company-1099-vendor-save}}
"/reports" {"" {:get :company-reports
:delete :company-reports-delete}
"/table" :company-reports-table}
"/table" :company-reports-table
"/expense" {:get :company-expense-report
"/card" :company-expense-report-card}}
"/yodlee" {"" {:get :company-yodlee}
"/table" {:get :company-yodlee-table}
"/fastlink" {:get :company-yodlee-fastlink-dialog}

View File

@@ -21,6 +21,14 @@
[vimsical.re-frame.cofx.inject :as inject]
[auto-ap.status :as status]))
(re-frame/reg-sub
::client
:<- [::subs/clients]
:<- [::subs/client]
(fn [[ clients client]]
(or client
(first clients))))
(def pie-chart (r/adapt-react-class recharts/PieChart))
(def pie (r/adapt-react-class recharts/Pie))
(def bar-chart (r/adapt-react-class recharts/BarChart))
@@ -239,8 +247,8 @@
(re-frame/reg-event-fx
::mounted
[(re-frame/inject-cofx ::inject/sub [::subs/client])]
(fn [{:keys [db] ::subs/keys [client]} _]
[(re-frame/inject-cofx ::inject/sub [::client]) ]
(fn [{:keys [db] ::keys [client]} _]
(cond->
{:db (assoc db ::top-expense-categories nil
::cash-flow nil
@@ -302,14 +310,19 @@
[grid/cell {:class "has-text-right"} (->$ amount)]])]]]))
(defn home-content []
(let [client-id (-> @(re-frame/subscribe [::subs/client]) :id)
(let [client @(re-frame/subscribe [::client])
client-id (-> client :id)
one-client (not (-> @(re-frame/subscribe [::subs/client]) :id))
chart-options @(re-frame/subscribe [::chart-options])
state @(re-frame/subscribe [::status/single ::page])]
^{:key client-id}
[side-bar-layout {:side-bar [:div]
:main [:div [:h1.title "Home"]
(if client-id
(if (= :loading (:state state))
(when one-client
[:h2.title.is-6 "Note: these reports are for "
(:name client) ". Please choose a specific customer for their report."])
(if (= :loading (:state state))
[:div.loader.is-loading.big.is-centered]
[:<>
@@ -350,17 +363,16 @@
(make-cash-flow-chart {:width 800 :height 500
:data (clj->js @(re-frame/subscribe [::cash-flow]))})
[cash-flow-grid]])
[:h2.title.is-6 "Please select a customer to see reports."])]}]))
[cash-flow-grid]])]}]))
(defn home-page []
(let [client-id (-> @(re-frame/subscribe [::subs/client]) :id)]
(let [client-id (-> @(re-frame/subscribe [::client]) :id)]
(re-frame/dispatch [::mounted])
^{:key client-id} [home-content]))
(defn home-page-with-vendor []
(let [client-id (-> @(re-frame/subscribe [::subs/client]) :id)
(let [client-id (-> @(re-frame/subscribe [::client]) :id)
user @(re-frame/subscribe [::subs/user])]
(re-frame/dispatch [::mounted])
(when (p/can? user {:subject :vendor