From d6211c778b3648220099176abc88ba46f5f79d6b Mon Sep 17 00:00:00 2001 From: Bryce Covert Date: Thu, 13 Jan 2022 08:08:20 -0800 Subject: [PATCH] makes expected deposit linking work. --- src/clj/auto_ap/datomic/expected_deposit.clj | 19 +++-- src/clj/auto_ap/datomic/migrate/sales.clj | 32 +++++++- src/clj/auto_ap/graphql.clj | 38 ++-------- src/clj/auto_ap/graphql/expected_deposit.clj | 73 +++++++++++++++++-- src/clj/auto_ap/import/transactions.clj | 47 ++++++------ src/clj/auto_ap/square/core.clj | 1 + .../views/pages/pos/expected_deposits.cljs | 3 +- .../pages/pos/expected_deposits/table.cljs | 59 +++++++++++---- test/clj/auto_ap/import/transactions_test.clj | 2 +- 9 files changed, 181 insertions(+), 93 deletions(-) diff --git a/src/clj/auto_ap/datomic/expected_deposit.clj b/src/clj/auto_ap/datomic/expected_deposit.clj index 81f11e39..02a4c678 100644 --- a/src/clj/auto_ap/datomic/expected_deposit.clj +++ b/src/clj/auto_ap/datomic/expected_deposit.clj @@ -1,18 +1,22 @@ (ns auto-ap.datomic.expected-deposit (:require [auto-ap.datomic :refer [add-sorter-fields apply-pagination apply-sort-3 merge-query conn]] [auto-ap.graphql.utils :refer [limited-clients]] - [auto-ap.utils :refer [dollars=]] [clj-time.coerce :as c] - [datomic.api :as d] - [clojure.tools.logging :as log])) + [datomic.api :as d])) (defn <-datomic [result] - (-> result - (update :expected-deposit/date c/from-date))) + (let [transaction (first (:transaction/_expected-deposit result)) + transaction (when transaction + (update transaction :transaction/date c/from-date))] + (cond-> result + true (update :expected-deposit/date c/from-date) + transaction (assoc :transaction transaction)))) (def default-read '[* - {:expected-deposit/client [:client/name :db/id :client/code]}]) + {:expected-deposit/client [:client/name :db/id :client/code] + :expected-deposit/status [:db/ident] + :transaction/_expected-deposit [:transaction/date :db/id]}]) (defn raw-graphql-ids [db args] (let [query (cond-> {:query {:find [] @@ -87,7 +91,7 @@ true (apply-sort-3 args) true (apply-pagination args)))) -(defn graphql-results [ids db args] +(defn graphql-results [ids db _] (let [results (->> (d/pull-many db default-read ids) (group-by :db/id)) payments (->> ids @@ -97,7 +101,6 @@ payments)) (defn get-graphql [args] - (log/info "ARGS" args) (let [db (d/db conn) {ids-to-retrieve :ids matching-count :count} (raw-graphql-ids db args)] diff --git a/src/clj/auto_ap/datomic/migrate/sales.clj b/src/clj/auto_ap/datomic/migrate/sales.clj index d498acf6..195e9c6e 100644 --- a/src/clj/auto_ap/datomic/migrate/sales.clj +++ b/src/clj/auto_ap/datomic/migrate/sales.clj @@ -1,6 +1,27 @@ (ns auto-ap.datomic.migrate.sales - (:require [datomic.api :as d] - [auto-ap.datomic :refer [uri]])) + (:require [datomic.api :as d])) + +(defn backfill-status [conn] + (let [db (d/db conn) + pendings (->> + (d/q '[:find [?ed ...] + :where [?ed :expected-deposit/date] + (not [_ :transaction/expected-deposit ?ed]) + (not [?ed :expected-deposit/status])] + db) + (map (fn [ed] + {:db/id ed + :expected-deposit/status :expected-deposit-status/pending}))) + cleared (->> + (d/q '[:find [?ed ...] + :where [?ed :expected-deposit/date] + [_ :transaction/expected-deposit ?ed] + (not [?ed :expected-deposit/status])] + db) + (map (fn [ed] + {:db/id ed + :expected-deposit/status :expected-deposit-status/cleared})))] + [(into pendings cleared)])) (def norms-map {:add-orders {:txes [[{:db/ident :sales-order/external-id :db/doc "The client for the sale" @@ -206,6 +227,7 @@ :db/doc "If this transaction is a deposit, the deposit that we anticipated" :db/valueType :db.type/ref :db/cardinality :db.cardinality/one}]]} + :add-vendor-for-sales-stuff {:txes [[{:db/ident :expected-deposit/vendor :db/doc "Which vendor is this deposit for? CCP Square?" :db/valueType :db.type/ref @@ -218,6 +240,12 @@ :db/doc "Which vendor is this refund for? CCP Square?" :db/valueType :db.type/ref :db/cardinality :db.cardinality/one}]]} + :backfill-status {:txes-fn `backfill-status + :requires [:add-expected-deposit-status + :add-expected-deposits + :add-sales-date + :add-vendor-for-sales-stuff + :add-orders]} :add-refund-type {:txes [[{:db/ident :sales-refund/type :db/doc "The type of refund" :db/valueType :db.type/string diff --git a/src/clj/auto_ap/graphql.clj b/src/clj/auto_ap/graphql.clj index 0d85c4de..b0d8fb6b 100644 --- a/src/clj/auto_ap/graphql.clj +++ b/src/clj/auto_ap/graphql.clj @@ -302,14 +302,7 @@ :charges {:type '(list :charge)} :line_items {:type '(list :order_line_item)}}} - :expected_deposit - {:fields {:id {:type :id} - :location {:type 'String} - :external_id {:type 'String} - :total {:type :money} - :fee {:type :money} - :client {:type :client} - :date {:type 'String}}} + :check {:fields {:id {:type :id} :type {:type 'String} @@ -470,11 +463,7 @@ - :expected_deposit_page {:fields {:expected_deposits {:type '(list :expected_deposit)} - :count {:type 'Int} - :total {:type 'Int} - :start {:type 'Int} - :end {:type 'Int}}} + :reminder_page {:fields {:reminders {:type '(list :reminder)} :count {:type 'Int} @@ -596,10 +585,7 @@ :statuses {:type '(list String)}} :resolve :get-all-payments} - :all_expected_deposits {:type '(list :expected_deposit) - :args {:client_id {:type :id} - :client_code {:type 'String}} - :resolve :get-all-expected-deposits} + :all_sales_orders {:type '(list :sales_order) :args {:client_id {:type :id} @@ -646,17 +632,7 @@ :resolve :get-sales-order-page} - :expected_deposit_page {:type :expected_deposit_page - :args {:client_id {:type :id} - :exact_match_id {:type :id} - :date_range {:type :date_range} - :total_lte {:type :money} - :total_gte {:type :money} - :start {:type 'Int} - :per_page {:type 'Int} - :sort {:type '(list :sort_item)}} - - :resolve :get-expected-deposit-page} + :payment_page {:type '(list :payment_page) :args {:client_id {:type :id} @@ -903,9 +879,6 @@ {:enum-value :cash} {:enum-value :debit}]} - - - :processor {:values [{:enum-value :na} {:enum-value :doordash} {:enum-value :uber_eats} @@ -1257,8 +1230,6 @@ :get-all-invoices gq-invoices/get-all-invoices :get-yodlee-provider-account-page gq-yodlee2/get-yodlee-provider-account-page :get-all-payments get-all-payments - :get-all-expected-deposits gq-expected-deposit/get-all-expected-deposits - :get-expected-deposit-page gq-expected-deposit/get-expected-deposit-page :get-all-sales-orders get-all-sales-orders :get-payment-page gq-checks/get-payment-page :get-potential-payments gq-checks/get-potential-payments @@ -1304,6 +1275,7 @@ gq-plaid/attach gq-import-batches/attach gq-transactions/attach + gq-expected-deposit/attach schema/compile)) diff --git a/src/clj/auto_ap/graphql/expected_deposit.clj b/src/clj/auto_ap/graphql/expected_deposit.clj index 7edd216f..a5976834 100644 --- a/src/clj/auto_ap/graphql/expected_deposit.clj +++ b/src/clj/auto_ap/graphql/expected_deposit.clj @@ -1,21 +1,78 @@ (ns auto-ap.graphql.expected-deposit - (:require [auto-ap.datomic.expected-deposit :as d-expected-deposit] - [auto-ap.graphql.utils - :refer - [->graphql <-graphql assert-admin result->page]])) + (:require + [auto-ap.datomic.expected-deposit :as d-expected-deposit] + [auto-ap.graphql.utils + :refer [->graphql <-graphql assert-admin ident->enum-f result->page]] + [com.walmartlabs.lacinia.util :refer [attach-resolvers]] + [clojure.tools.logging :as log])) + +(def status->graphql (ident->enum-f :expected-deposit/status)) (defn get-expected-deposit [context args value] (let [args (assoc args :id (:id context)) [sales-orders sales-orders-count] (d-expected-deposit/get-graphql (<-graphql args))] - (result->page sales-orders sales-orders-count :data args ))) + (result->page sales-orders sales-orders-count :data args))) (defn get-all-expected-deposits [context args value] (assert-admin (:id context)) (map - ->graphql + (comp ->graphql status->graphql) (first (d-expected-deposit/get-graphql (assoc (<-graphql args) :count Integer/MAX_VALUE))))) (defn get-expected-deposit-page [context args value] (let [args (assoc args :id (:id context)) - [expected-deposits expected-deposit-count] (d-expected-deposit/get-graphql (<-graphql args))] - (result->page expected-deposits expected-deposit-count :expected_deposits args ))) + [expected-deposits expected-deposit-count] (d-expected-deposit/get-graphql (<-graphql args)) + _ (log/info expected-deposits) + expected-deposits (map status->graphql expected-deposits)] + + (result->page expected-deposits expected-deposit-count :expected_deposits args))) + +(def objects + {:expected_deposit {:fields {:id {:type :id} + :location {:type 'String} + :external_id {:type 'String} + :total {:type :money} + :transaction {:type :transaction} + :status {:type :expected_deposit_status} + :fee {:type :money} + :client {:type :client} + :date {:type 'String}}} + + :expected_deposit_page {:fields {:expected_deposits {:type '(list :expected_deposit)} + :count {:type 'Int} + :total {:type 'Int} + :start {:type 'Int} + :end {:type 'Int}}}}) + +(def queries + {:expected_deposit_page {:type :expected_deposit_page + :args {:client_id {:type :id} + :exact_match_id {:type :id} + :date_range {:type :date_range} + :total_lte {:type :money} + :total_gte {:type :money} + :start {:type 'Int} + :per_page {:type 'Int} + :sort {:type '(list :sort_item)}} + + :resolve :get-expected-deposit-page} + :all_expected_deposits {:type '(list :expected_deposit) + :args {:client_id {:type :id} + :client_code {:type 'String}} + :resolve :get-all-expected-deposits}}) + +(def enums + {:expected_deposit_status {:values [{:enum-value :cleared} + {:enum-value :pending}]}}) + +(def resolvers + {:get-all-expected-deposits get-all-expected-deposits + :get-expected-deposit-page get-expected-deposit-page}) + +(defn attach [schema] + (-> + (merge-with merge schema + {:objects objects + :queries queries + :enums enums}) + (attach-resolvers resolvers))) diff --git a/src/clj/auto_ap/import/transactions.clj b/src/clj/auto_ap/import/transactions.clj index b3a0aa6d..96a7e8d5 100644 --- a/src/clj/auto_ap/import/transactions.clj +++ b/src/clj/auto_ap/import/transactions.clj @@ -150,7 +150,7 @@ (defn find-expected-deposit [client-id amount date] (when date (-> (d/q - '[:find ?ed + '[:find [(pull ?ed [:db/id {:expected-deposit/vendor [:db/id]}]) ...] :in $ ?c ?a ?d-start :where [?ed :expected-deposit/client ?c] @@ -161,40 +161,35 @@ [(auto-ap.utils/dollars= ?a2 ?a)] ] (d/db conn) client-id amount (coerce/to-date (t/plus date (t/days -10)))) - first first))) (defn categorize-transaction [transaction bank-account existing] - (let [bank-account-id (:db/id bank-account) - client (:client/_bank-accounts bank-account) - client-id (:db/id client) - valid-locations (or (:bank-account/locations bank-account) (:client/locations client))] - (cond (= :transaction-approval-status/suppressed (existing (:transaction/id transaction))) - :suppressed + (cond (= :transaction-approval-status/suppressed (existing (:transaction/id transaction))) + :suppressed - (existing (:transaction/id transaction)) - :extant + (existing (:transaction/id transaction)) + :extant - (not (:transaction/client transaction)) - :error + (not (:transaction/client transaction)) + :error - (not (:transaction/bank-account transaction)) - :error + (not (:transaction/bank-account transaction)) + :error - (not (:transaction/id transaction)) - :error + (not (:transaction/id transaction)) + :error - (not= "POSTED" (:transaction/status transaction)) - :not-ready + (not= "POSTED" (:transaction/status transaction)) + :not-ready - (and (:bank-account/start-date bank-account) - (not (t/after? (coerce/to-date-time (:transaction/date transaction)) - (-> bank-account :bank-account/start-date coerce/to-date-time)))) - :not-ready + (and (:bank-account/start-date bank-account) + (not (t/after? (coerce/to-date-time (:transaction/date transaction)) + (-> bank-account :bank-account/start-date coerce/to-date-time)))) + :not-ready - :else - :import))) + :else + :import)) (defn maybe-assoc-check-number [transaction] (if-let [check-number (or (:transaction/check-number transaction) @@ -224,13 +219,13 @@ (when (>= amount 0.0) (when-let [expected-deposit (find-expected-deposit client amount (coerce/to-date-time date))] (assoc transaction - :transaction/expected-deposit {:db/id expected-deposit + :transaction/expected-deposit {:db/id (:db/id expected-deposit) :expected-deposit/status :expected-deposit-status/cleared} :transaction/accounts [{:transaction-account/account :account/ccp :transaction-account/amount amount :transaction-account/location "A"}] :transaction/approval-status :transaction-approval-status/approved - :transaction/vendor (:expected-deposit/vendor expected-deposit) + :transaction/vendor (:db/id (:expected-deposit/vendor expected-deposit)) )))) (defn maybe-code [{:transaction/keys [client amount] :as transaction} apply-rules valid-locations] diff --git a/src/clj/auto_ap/square/core.clj b/src/clj/auto_ap/square/core.clj index 8ff6f0d2..9e7144e3 100644 --- a/src/clj/auto_ap/square/core.clj +++ b/src/clj/auto_ap/square/core.clj @@ -336,6 +336,7 @@ (->> (for [settlement (settlements client location-id)] #:expected-deposit {:external-id (str "square/settlement/" (:id settlement)) :vendor :vendor/ccp-square + :status :expected-deposit-status/pending :total (amount->money (:total_money settlement)) :client [:client/code client] :location (get-in env [:square-config client :location]) diff --git a/src/cljs/auto_ap/views/pages/pos/expected_deposits.cljs b/src/cljs/auto_ap/views/pages/pos/expected_deposits.cljs index 2c0dc792..92994a87 100644 --- a/src/cljs/auto_ap/views/pages/pos/expected_deposits.cljs +++ b/src/cljs/auto_ap/views/pages/pos/expected_deposits.cljs @@ -27,7 +27,8 @@ :total-lte (:amount-lte (:total-range params)) :date-range (:date-range params) :client-id (:id @(re-frame/subscribe [::subs/client]))} - [[:expected-deposits [:id :total :fee :location :date + [[:expected-deposits [:id :total :fee :location :date :status + [:transaction [:id :date]] [:client [:name :id]]]] :total :start diff --git a/src/cljs/auto_ap/views/pages/pos/expected_deposits/table.cljs b/src/cljs/auto_ap/views/pages/pos/expected_deposits/table.cljs index 2234b275..36625b3a 100644 --- a/src/cljs/auto_ap/views/pages/pos/expected_deposits/table.cljs +++ b/src/cljs/auto_ap/views/pages/pos/expected_deposits/table.cljs @@ -1,32 +1,62 @@ (ns auto-ap.views.pages.pos.expected-deposits.table - (:require [auto-ap.subs :as subs] - [auto-ap.views.components.buttons :as buttons] [auto-ap.views.components.grid :as grid] - [auto-ap.views.pages.data-page :as data-page] - [auto-ap.views.pages.pos.form :as form] - [auto-ap.views.utils :refer [date->str nf]] - [clojure.string :as str] - [re-frame.core :as re-frame])) + (:require + [auto-ap.events :as events] + [auto-ap.subs :as subs] + [auto-ap.views.components.buttons :as buttons] + [auto-ap.views.components.grid :as grid] + [auto-ap.views.pages.data-page :as data-page] + [auto-ap.views.pages.pos.form :as form] + [auto-ap.views.utils :refer [date->str nf dispatch-event-with-propagation pretty str->date standard]] + [auto-ap.views.components.dropdown + :refer + [drop-down drop-down-contents]] -(defn row [{sales-order :sales-order + [bidi.bidi :as bidi] + [cemerick.url :as url] + [re-frame.core :as re-frame] + [auto-ap.routes :as routes])) + +(defn row [{sales-order :sales-order selected-client :selected-client}] - (let [{:keys [client location date total fee id]} sales-order] + (let [{:keys [client transaction status location date total fee id]} sales-order] [grid/row {:class (:class sales-order) :id id} (when-not selected-client [grid/cell {} (:name client)]) [grid/cell location ] [grid/cell {} (date->str date) ] + [grid/cell {} status ] [grid/cell {:class "has-text-right"} (nf total )] [grid/cell {:class "has-text-right"} (nf fee )] - -[grid/button-cell {} + [grid/button-cell {} [:div.buttons - [buttons/fa-icon {:event [::form/editing sales-order] :icon "fa-pencil"}]]]])) + [buttons/fa-icon {:event [::form/editing sales-order] :icon "fa-pencil"}]] + (when transaction + [drop-down {:id [::links id] + :is-right? true + :header [buttons/fa-icon {:class "badge" + :on-click (dispatch-event-with-propagation [::events/toggle-menu [::links id]]) + :data-badge (str 1) + :icon "fa-paperclip"}]} + [drop-down-contents + [:div.dropdown-item + [:table.table.grid.compact + [:tbody + (when transaction + [:tr + [:td + "Transaction"] + [:td (some-> transaction :date (date->str pretty))] + [:td + [buttons/fa-icon {:icon "fa-external-link" + :href (str (bidi/path-for routes/routes :transactions ) + "?" + (url/map->query {:exact-match-id (:id transaction)}))}]]])]]]]])]])) (defn table [{:keys [data-page]}] - (let [selected-client @(re-frame/subscribe [::subs/client]) + (let [selected-client @(re-frame/subscribe [::subs/client]) {:keys [data status]} @(re-frame/subscribe [::data-page/page data-page])] - [grid/grid {:data-page data-page + [grid/grid {:data-page data-page :column-count (if selected-client 7 8)} [grid/controls data] [grid/table {:fullwidth true} @@ -36,6 +66,7 @@ [grid/sortable-header-cell {:sort-key "client" :sort-name "Client"} "Client"]) [grid/sortable-header-cell {:sort-key "location" :sort-name "Location" :style {:width "7em"}} "Location"] [grid/sortable-header-cell {:sort-key "date" :sort-name "Date" :style {:width "8em"}} "Date"] + [grid/sortable-header-cell {:sort-key "status" :sort-name "Status" :style {:width "8em"}} "Status"] [grid/sortable-header-cell {:sort-key "total" :sort-name "Total" :class "has-text-right" :style {:width "8em"}} "Total"] [grid/sortable-header-cell {:sort-key "fee" :sort-name "Fee" :class "has-text-right" :style {:width "7em"}} "Fee"] diff --git a/test/clj/auto_ap/import/transactions_test.clj b/test/clj/auto_ap/import/transactions_test.clj index 3273fcb3..6ce3aaf5 100644 --- a/test/clj/auto_ap/import/transactions_test.clj +++ b/test/clj/auto_ap/import/transactions_test.clj @@ -166,7 +166,7 @@ (d/entity (d/db conn) bank-account-id) noop-rule)] (t/is (= expected-deposit-id - (sut/find-expected-deposit client-id 100.0 (clj-time.coerce/to-date-time #inst "2021-07-03T00:00:00-08:00")))) + (:db/id (sut/find-expected-deposit client-id 100.0 (clj-time.coerce/to-date-time #inst "2021-07-03T00:00:00-08:00"))))) (t/is (= {:db/id expected-deposit-id :expected-deposit/status :expected-deposit-status/cleared}