From f547911c5b09765a4e88043575e8994b260e3042 Mon Sep 17 00:00:00 2001 From: Bryce Covert Date: Wed, 24 Apr 2019 07:35:19 -0700 Subject: [PATCH] tells you about potential matches. --- src/clj/auto_ap/graphql.clj | 4 + src/clj/auto_ap/graphql/checks.clj | 10 +++ .../components/expense_accounts_field.cljs | 21 ++++-- src/cljs/auto_ap/views/pages/checks.cljs | 2 +- .../views/pages/transactions/form.cljs | 73 +++++++++++++------ .../views/pages/transactions/table.cljs | 28 ++++++- 6 files changed, 104 insertions(+), 34 deletions(-) diff --git a/src/clj/auto_ap/graphql.clj b/src/clj/auto_ap/graphql.clj index e0c82078..9cf900f9 100644 --- a/src/clj/auto_ap/graphql.clj +++ b/src/clj/auto_ap/graphql.clj @@ -275,6 +275,9 @@ :args {:client_id {:type :id}} :resolve :get-invoice-stats} + :potential_payment_matches {:type '(list :payment) + :args {:transaction_id {:type :id}} + :resolve :get-potential-payments} :balance_sheet {:type :balance_sheet :args {:client_id {:type :id} :date {:type 'String}} @@ -676,6 +679,7 @@ :get-all-invoices gq-invoices/get-all-invoices :get-all-payments get-all-payments :get-payment-page gq-checks/get-payment-page + :get-potential-payments gq-checks/get-potential-payments :get-accounts gq-accounts/get-accounts :get-transaction-page gq-transactions/get-transaction-page :get-ledger-page gq-ledger/get-ledger-page diff --git a/src/clj/auto_ap/graphql/checks.clj b/src/clj/auto_ap/graphql/checks.clj index f0b7dea9..dd6fb49a 100644 --- a/src/clj/auto_ap/graphql/checks.clj +++ b/src/clj/auto_ap/graphql/checks.clj @@ -8,6 +8,7 @@ [auto-ap.datomic.checks :as d-checks] [auto-ap.datomic.invoices :as d-invoices] [auto-ap.datomic.vendors :as d-vendors] + [auto-ap.datomic.transactions :as d-transactions] [auto-ap.datomic.clients :as d-clients] [auto-ap.datomic.bank-accounts :as d-bank-accounts] [auto-ap.datomic :refer [uri remove-nils]] @@ -329,6 +330,15 @@ :start (:start args 0) :end (+ (:start args 0) (count payments))}])) +(defn get-potential-payments [context args value] + (let [transaction (d-transactions/get-by-id (:transaction_id args)) + _ (assert-can-see-client (:id context) (:transaction/client transaction))] + (map ->graphql + (d-checks/get-graphql {:client-id (:db/id (:transaction/client transaction)) + :bank-account-id (:db/id (:transaction/bank-account transaction)) + :amount (- (:transaction/amount transaction)) + :status :payment-status/pending})))) + (defn add-handwritten-check [context args value] (let [invoices (d-invoices/get-multi (map :invoice_id (:invoice_payments args))) bank-account-id (:bank_account_id args) diff --git a/src/cljs/auto_ap/views/components/expense_accounts_field.cljs b/src/cljs/auto_ap/views/components/expense_accounts_field.cljs index f644630b..6be030d7 100644 --- a/src/cljs/auto_ap/views/components/expense_accounts_field.cljs +++ b/src/cljs/auto_ap/views/components/expense_accounts_field.cljs @@ -67,7 +67,7 @@ ;; VIEWS -(defn expense-accounts-field [{expense-accounts :value max-value :max locations :locations event :event descriptor :descriptor}] +(defn expense-accounts-field [{expense-accounts :value max-value :max locations :locations event :event descriptor :descriptor disabled :disabled}] (let [chooseable-expense-accounts @(re-frame/subscribe [::subs/chooseable-expense-accounts]) accounts-by-id @(re-frame/subscribe [::subs/accounts-for-client-by-id])] [:div @@ -76,9 +76,10 @@ [:h1.subtitle.is-4.is-inline (str/capitalize descriptor) "s"] [:p.help "Remaining " (->$ (- max-value (reduce + 0 (map (comp js/parseFloat :amount) expense-accounts))))]] [:div.column.is-narrow - [:p.buttons - [:a.button {:on-click (dispatch-event [::spread-evenly event expense-accounts max-value])} "Spread evenly"] - [:a.button {:on-click (dispatch-event [::add-expense-account event expense-accounts])} "Add"]]]] + (when-not disabled + [:p.buttons + [:a.button {:on-click (dispatch-event [::spread-evenly event expense-accounts max-value])} "Spread evenly"] + [:a.button {:on-click (dispatch-event [::add-expense-account event expense-accounts])} "Add"]])]] (for [[index {:keys [account id location amount amount-mode] :as expense-account}] (map vector (range) expense-accounts) :let [account (accounts-by-id (:id account))]] @@ -92,7 +93,8 @@ (gstring/format "$%.2f" (or amount 0) )) [:i "New " descriptor])]] [:div.column.is-narrow - [:a.button {:on-click (dispatch-event [::remove-expense-account event expense-accounts id])} [:span.icon [:i.fa.fa-times]]]]] + (when-not disabled + [:a.button {:on-click (dispatch-event [::remove-expense-account event expense-accounts id])} [:span.icon [:i.fa.fa-times]]])]] [:div.field [:div.columns [:div.column @@ -100,6 +102,7 @@ [:div.control.is-fullwidth [bind-field [typeahead {:matches (map (fn [x] [(:id x) (str (:numeric-code x) " - " (:name x))]) chooseable-expense-accounts) + :disabled disabled :type "typeahead" :field [index :account :id] #_#_:text-field [index :account :name] @@ -115,9 +118,8 @@ [:div.select [bind-field [:select {:type "select" - :disabled (if (:location account) - "disabled" - "") + :disabled (boolean (or (:location account) + disabled)) :style {:width "5em"} :field [index :location] :allow-nil? true @@ -134,6 +136,7 @@ [:p.control [:span.select [bind-field [:select {:type "select" + :disabled disabled :field [index :amount-mode] :allow-nil? false :event [::expense-account-changed event expense-accounts max-value] @@ -147,6 +150,7 @@ :field [index :amount] :style {:text-align "right" :width "7em"} :event [::expense-account-changed event expense-accounts max-value] + :disabled disabled :subscription expense-accounts :precision 2 :value (get-in expense-account [:amount]) @@ -156,6 +160,7 @@ [:input.input {:type "number" :field [index :amount-percentage] :style {:text-align "right" :width "7em"} + :disabled disabled :event [::expense-account-changed event expense-accounts max-value] :precision 2 :subscription expense-accounts diff --git a/src/cljs/auto_ap/views/pages/checks.cljs b/src/cljs/auto_ap/views/pages/checks.cljs index bd45149e..618640ec 100644 --- a/src/cljs/auto_ap/views/pages/checks.cljs +++ b/src/cljs/auto_ap/views/pages/checks.cljs @@ -214,7 +214,7 @@ [:td status] [:td (when (or (= :pending status) - (and (#{":cash" :cash } type) + (and (#{":cash" :cash} type) (not= :voided status))) [:button.button.is-warning.is-outlined {:on-click (dispatch-event [::void-check i])} [:span [:span.icon [:i.fa.fa-minus-circle]]]]) (if s3-url diff --git a/src/cljs/auto_ap/views/pages/transactions/form.cljs b/src/cljs/auto_ap/views/pages/transactions/form.cljs index ac3c844d..7098a295 100644 --- a/src/cljs/auto_ap/views/pages/transactions/form.cljs +++ b/src/cljs/auto_ap/views/pages/transactions/form.cljs @@ -4,7 +4,7 @@ [auto-ap.views.components.typeahead :refer [typeahead]] [auto-ap.views.components.expense-accounts-field :refer [expense-accounts-field]] [auto-ap.views.pages.transactions.common :refer [transaction-read]] - [auto-ap.views.utils :refer [bind-field]] + [auto-ap.views.utils :refer [bind-field dispatch-event]] [re-frame.core :as re-frame] [clojure.string :as str])) @@ -43,14 +43,16 @@ (re-frame/reg-event-db ::editing - (fn [db [_ which]] + (fn [db [_ which potential-payment-matches]] (-> db (forms/start-form ::edit-transaction {:id (:id which) :yodlee-merchant (:yodlee-merchant which) :amount (:amount which) + :potential-payment-matches potential-payment-matches :description-original (:description-original which) :location (:location which) :exclude-from-ledger (:exclude-from-ledger which) + :payment (:payment which) :client-id (:id (:client which)) :vendor-id (:id (:vendor which)) :vendor-name (:name (:vendor which)) @@ -94,6 +96,11 @@ [::forms/change ::edit-transaction [:location] forced-location]]} {:dispatch [::forms/change ::edit-transaction f a]}))) +(re-frame/reg-event-db + ::manual-match + [(forms/in-form ::edit-transaction)] + (fn [edit-transaction] + (update-in edit-transaction [:data] dissoc :potential-payment-matches))) ;; VIEWS @@ -143,30 +150,48 @@ :subscription data}]]]] - [:div.field - [:p.help "Vendor"] - [:div.control - [bind-field - [typeahead {:matches (map (fn [x] [(:id x) (:name x)]) @(re-frame/subscribe [::subs/vendors])) - :type "typeahead" - :auto-focus true - :field [:vendor-id] - :text-field [:vendor-name] - :event change-event - :subscription data}]]]] + (if (seq (:potential-payment-matches data)) - + [:div.box + [:div.columns + [:div.column + [:h1.subtitle.is-5 "Potentially matching payments:"]] + [:div.column.is-narrow + [:a.button {:on-click (dispatch-event [::manual-match])} [:i.fa.fa-times]]]] + + [:ul + (list + (for [{:keys [memo vendor]} (:potential-payment-matches data)] + [:li (:name vendor) " - " memo " " [:a.button.is-primary.is-small "Match"]] + ))] + ] + [:div + [:div.field + [:p.help "Vendor"] + [:div.control + [bind-field + [typeahead {:matches (map (fn [x] [(:id x) (:name x)]) @(re-frame/subscribe [::subs/vendors])) + :type "typeahead" + :auto-focus true + :field [:vendor-id] + :text-field [:vendor-name] + :disabled (boolean (:payment data)) + :event change-event + :subscription data}]]]] - [:div.field - [bind-field - [expense-accounts-field - {:type "expense-accounts" - :field [:accounts] - :max (Math/abs (js/parseFloat (:amount data))) - :descriptor "credit account" - :locations locations - :event change-event - :subscription data}]]] + + + [:div.field + [bind-field + [expense-accounts-field + {:type "expense-accounts" + :field [:accounts] + :max (Math/abs (js/parseFloat (:amount data))) + :descriptor "credit account" + :disabled (boolean (:payment data)) + :locations locations + :event change-event + :subscription data}]]]]) [:div.field [:div.control diff --git a/src/cljs/auto_ap/views/pages/transactions/table.cljs b/src/cljs/auto_ap/views/pages/transactions/table.cljs index 36b989ef..9bea9da0 100644 --- a/src/cljs/auto_ap/views/pages/transactions/table.cljs +++ b/src/cljs/auto_ap/views/pages/transactions/table.cljs @@ -6,6 +6,32 @@ [auto-ap.views.utils :refer [date->str dispatch-event nf]] [goog.string :as gstring] [re-frame.core :as re-frame])) +(re-frame/reg-event-fx + ::editing-matches-found + (fn [{:keys [db]} [_ which payment-matches]] + (println "FOUND" payment-matches) + + {:dispatch + [::edit/editing which (:potential-payment-matches payment-matches)]})) + +(re-frame/reg-event-fx + ::editing-matches-failed + (fn [{:keys [db]} [_ which payment-matches]] + (println "FAILED" payment-matches) + + {:dispatch + [::edit/editing which payment-matches]})) + +(re-frame/reg-event-fx + ::intend-to-edit + (fn [{:keys [db]} [_ which]] + {:graphql + {:token (-> db :user) + :query-obj {:venia/queries [{:query/data [:potential-payment-matches + {:transaction_id (:id which)} + [:id :memo [:vendor [:name]]]]}]} + :on-success [::editing-matches-found which] + :on-error [::editing-matches-failed which]}} )) (defn table [{:keys [id transaction-page status on-params-change vendors params check-boxes checked on-check-changed expense-event]}] (let [opc (fn [p] @@ -96,7 +122,7 @@ [:td status] [:td (:name bank-account )] [:td - [:a.button {:on-click (dispatch-event [::edit/editing i])} [:span [:span.icon [:i.fa.fa-pencil]]]] + [:a.button {:on-click (dispatch-event [::intend-to-edit i])} [:span [:span.icon [:i.fa.fa-pencil]]]] (when payment [:a.tag {:href (:s3-url payment) :target "_new"} #_[:i.fa.fa-money-check]