begun on unpaid invoice match.
This commit is contained in:
@@ -170,7 +170,7 @@
|
||||
transaction)))
|
||||
(map #(dissoc % :transaction/id))
|
||||
(group-by :db/id))]
|
||||
(clojure.pprint/pprint results)
|
||||
|
||||
(->> ids
|
||||
(map results)
|
||||
(map first))))
|
||||
|
||||
@@ -515,6 +515,9 @@
|
||||
:potential_autopay_invoices_matches {:type '(list (list :invoice))
|
||||
:args {:transaction_id {:type :id}}
|
||||
:resolve :get-potential-autopay-invoices-matches}
|
||||
:potential_unpaid_invoices_matches {:type '(list (list :invoice))
|
||||
:args {:transaction_id {:type :id}}
|
||||
:resolve :get-potential-unpaid-invoices-matches}
|
||||
|
||||
:potential_transaction_rule_matches {:type '(list :transaction_rule)
|
||||
:args {:transaction_id {:type :id}}
|
||||
@@ -1239,6 +1242,7 @@
|
||||
:get-payment-page gq-checks/get-payment-page
|
||||
:get-potential-payments gq-checks/get-potential-payments
|
||||
:get-potential-autopay-invoices-matches gq-transactions/get-potential-autopay-invoices-matches
|
||||
:get-potential-unpaid-invoices-matches gq-transactions/get-potential-unpaid-invoices-matches
|
||||
:get-accounts gq-accounts/get-accounts
|
||||
:get-transaction-page gq-transactions/get-transaction-page
|
||||
:get-ledger-page gq-ledger/get-ledger-page
|
||||
|
||||
@@ -93,6 +93,16 @@
|
||||
(for [[_ invoice-id ] matches]
|
||||
(d-invoices/get-by-id invoice-id)))))))
|
||||
|
||||
(defn get-potential-unpaid-invoices-matches [context args value]
|
||||
(assert-admin (:id context))
|
||||
(let [transaction (d-transactions/get-by-id (:transaction_id args))]
|
||||
|
||||
(let [matches-set (import/match-transaction-to-unpaid-invoices (:transaction/amount transaction)
|
||||
(:db/id (:transaction/client transaction)))]
|
||||
(->graphql (for [matches matches-set]
|
||||
(for [[_ invoice-id ] matches]
|
||||
(d-invoices/get-by-id invoice-id)))))))
|
||||
|
||||
(defn unlink-transaction [context args value]
|
||||
(let [_ (assert-admin (:id context))
|
||||
args (assoc args :id (:id context))
|
||||
|
||||
@@ -74,7 +74,7 @@
|
||||
(group-by first) ;; group by vendors
|
||||
vals)
|
||||
considerations (for [candidate-invoices candidate-invoices-vendor-groups
|
||||
invoice-count (range 1 30)
|
||||
invoice-count (range 1 32)
|
||||
consideration (partition invoice-count 1 candidate-invoices)
|
||||
:when (dollars= (reduce (fn [acc [_ _ amount]]
|
||||
(+ acc amount)) 0.0 consideration)
|
||||
@@ -84,6 +84,30 @@
|
||||
considerations
|
||||
))
|
||||
|
||||
(defn match-transaction-to-unpaid-invoices [amount client-id]
|
||||
(log/info "trying to find unpaid invoices for " client-id amount)
|
||||
(let [candidate-invoices-vendor-groups (->> (d/query {:query {:find ['?vendor-id '?e '?total '?d]
|
||||
:in ['$ '?client-id]
|
||||
:where ['[?e :invoice/client ?client-id]
|
||||
'[?e :invoice/status :invoice-status/unpaid]
|
||||
'(not [_ :invoice-payment/invoice ?e])
|
||||
'[?e :invoice/vendor ?vendor-id]
|
||||
'[?e :invoice/total ?total]
|
||||
'[?e :invoice/date ?d]]}
|
||||
:args [(d/db conn) client-id]})
|
||||
(sort-by last) ;; sort by scheduled payment date
|
||||
(group-by first) ;; group by vendors
|
||||
vals)
|
||||
considerations (for [candidate-invoices candidate-invoices-vendor-groups
|
||||
invoice-count (range 1 32)
|
||||
consideration (partition invoice-count 1 candidate-invoices)
|
||||
:when (dollars= (reduce (fn [acc [_ _ amount]]
|
||||
(+ acc amount)) 0.0 consideration)
|
||||
(- amount))]
|
||||
consideration)]
|
||||
(log/info "Found " (count considerations) "unpaid invoice considerations for transaction of" amount)
|
||||
considerations))
|
||||
|
||||
(defn match-transaction-to-single-unfulfilled-autopayments [amount client-id]
|
||||
(let [considerations (match-transaction-to-unfulfilled-autopayments amount client-id)]
|
||||
(if (= 1 (count considerations))
|
||||
@@ -127,6 +151,7 @@
|
||||
nil))
|
||||
|
||||
(defn transactions->txs [transactions transaction->bank-account apply-rules existing]
|
||||
(log/info transactions)
|
||||
|
||||
(into []
|
||||
|
||||
@@ -163,8 +188,10 @@
|
||||
(t/after? date (:start-date bank-account)))
|
||||
)]
|
||||
(let [existing-check (transaction->existing-payment transaction check-number client-id bank-account-id amount id)
|
||||
invoices-matches (when-not existing-check
|
||||
(match-transaction-to-single-unfulfilled-autopayments amount client-id ))]
|
||||
autopay-invoices-matches (when-not existing-check
|
||||
(match-transaction-to-unfulfilled-autopayments amount client-id ))
|
||||
unpaid-invoices-matches (when-not existing-check
|
||||
(match-transaction-to-unpaid-invoices amount client-id ))]
|
||||
(cond->
|
||||
[#:transaction
|
||||
{:post-date (coerce/to-date (time/parse post-date "YYYY-MM-dd"))
|
||||
@@ -190,11 +217,12 @@
|
||||
:location "A"
|
||||
:amount (Math/abs (double amount))}]))
|
||||
|
||||
(and (not existing-check)
|
||||
(seq invoices-matches)) (add-new-payment invoices-matches bank-account-id client-id)
|
||||
#_(and (not existing-check)
|
||||
(seq autopay-invoices-matches)) #_(add-new-payment autopay-invoices-matches bank-account-id client-id)
|
||||
|
||||
|
||||
true (update 0 #(apply-rules % valid-locations))
|
||||
(and (not (seq autopay-invoices-matches))
|
||||
(not (seq unpaid-invoices-matches))) (update 0 #(apply-rules % valid-locations))
|
||||
true (update 0 remove-nils))))))
|
||||
|
||||
|
||||
@@ -251,9 +279,10 @@
|
||||
transaction->bank-account (comp all-bank-accounts :bank-account-id)]
|
||||
(log/info "Importing " (count transformed-transactions) " manual transactions")
|
||||
|
||||
(let [result (batch-transact
|
||||
(transactions->txs transformed-transactions transaction->bank-account (rm/rule-applying-fn all-rules) (get-existing)))]
|
||||
(log/info "Imported " (count result) " manual transactions")))))
|
||||
(doseq [tx (transactions->txs transformed-transactions transaction->bank-account (rm/rule-applying-fn all-rules) (get-existing))]
|
||||
(audit-transact tx {:user/name "Yodlee import"
|
||||
:user/role ":admin"}))
|
||||
(log/info "Imported manual transactions"))))
|
||||
|
||||
(defn do-import
|
||||
([]
|
||||
|
||||
@@ -53,7 +53,7 @@
|
||||
|
||||
(re-frame/reg-event-db
|
||||
::editing
|
||||
(fn [db [_ which potential-payment-matches potential-autopay-invoices-matches potential-transaction-rule-matches]]
|
||||
(fn [db [_ which potential-payment-matches potential-autopay-invoices-matches potential-unpaid-invoices-matches potential-transaction-rule-matches]]
|
||||
(let [locations @(re-frame/subscribe [::subs/locations-for-client (:id (:client which))])
|
||||
accounts-by-id @(re-frame/subscribe [::subs/accounts-by-id (:client which)])]
|
||||
(forms/start-form db ::form
|
||||
@@ -68,6 +68,7 @@
|
||||
(assoc :potential-payment-matches potential-payment-matches)
|
||||
(assoc :potential-transaction-rule-matches potential-transaction-rule-matches)
|
||||
(assoc :potential-autopay-invoices-matches potential-autopay-invoices-matches)
|
||||
(assoc :potential-unpaid-invoices-matches potential-unpaid-invoices-matches)
|
||||
(update :accounts expense-accounts-field/from-graphql accounts-by-id (:amount which) locations))))))
|
||||
|
||||
(re-frame/reg-event-db
|
||||
@@ -247,6 +248,30 @@
|
||||
"Match"]]]))]]))
|
||||
|
||||
|
||||
(defn potential-unpaid-invoices-matches-box [{:keys [potential-unpaid-invoices-matches] :as params}]
|
||||
(let [states @(re-frame/subscribe [::status/multi ::matching])]
|
||||
[:div
|
||||
[:div.notification.is-light.is-info "This transaction may match the following unpaid invoice(s)."]
|
||||
[:table.table.grid.is-fullwidth
|
||||
(list
|
||||
(for [invoices potential-unpaid-invoices-matches]
|
||||
^{:key (str invoices)}
|
||||
[:tr
|
||||
[:td {:style {:width "30%"}} (:name (:vendor (first invoices)))]
|
||||
[:td {:style {:overflow "visible" :width "60%"}} [:span.has-tooltip-arrow.has-tooltip-bottom {:data-tooltip (str/join "\n"
|
||||
(for [i invoices]
|
||||
(str (:invoice-number i) " (" (->$ (:total i)) ")"))
|
||||
)}
|
||||
(count invoices) " invoices" (if (> (count invoices) 1)
|
||||
(str " from " (date->str (:date (first invoices))) " - " (date->str (:date (last invoices))))
|
||||
(str " on " (date->str (:date (first invoices)))))]]
|
||||
[:td {:style {:width "6em"}}
|
||||
[:a.button.is-primary.is-small {:on-click (dispatch-event [::matching-unpaid-invoices (map :id invoices)])
|
||||
:class (status/class-for (get states [:unpaid-invoices (map :id invoices)]))
|
||||
:disabled (status/disabled-if-any states)}
|
||||
"Match"]]]))]]))
|
||||
|
||||
|
||||
(defonce ^js/React.Context current-tab-context ( react/createContext "default"))
|
||||
(def ^js/React.Provider CurrentTabProvider (. current-tab-context -Provider))
|
||||
#_(println "Provider is" Provider)
|
||||
@@ -267,7 +292,7 @@
|
||||
(into [:div]
|
||||
(->> (r/children (r/current-component))
|
||||
(filter identity)
|
||||
(filter #(= (doto (:key (second %)) println) current-tab-v) )
|
||||
(filter #(= (:key (second %)) current-tab-v) )
|
||||
first
|
||||
(drop 2)))]))))))
|
||||
|
||||
@@ -340,10 +365,17 @@
|
||||
|
||||
(when
|
||||
(and (seq (:potential-autopay-invoices-matches data))
|
||||
#_(not is-already-matched?)
|
||||
is-admin?)
|
||||
[tab {:title "Autopay Invoices" :key :autopay-invoices}
|
||||
[potential-autopay-invoices-matches-box {:potential-autopay-invoices-matches (:potential-autopay-invoices-matches data)}]])
|
||||
|
||||
(when
|
||||
(and (seq (:potential-unpaid-invoices-matches data))
|
||||
(not is-already-matched?)
|
||||
is-admin?)
|
||||
[tab {:title "Autopay invoices" :key :autopay-invoices}
|
||||
[potential-autopay-invoices-matches-box {:potential-autopay-invoices-matches (:potential-autopay-invoices-matches data)}]])
|
||||
[tab {:title "Unpaid Invoices" :key :unpaid-invoices}
|
||||
[potential-unpaid-invoices-matches-box {:potential-unpaid-invoices-matches (:potential-unpaid-invoices-matches data)}]])
|
||||
|
||||
(when
|
||||
(and (seq (:potential-payment-matches data))
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
::editing-matches-found
|
||||
(fn [{:keys [db]} [_ which matches]]
|
||||
{:dispatch
|
||||
[::edit/editing which (:potential-payment-matches matches) (:potential-autopay-invoices-matches matches) (:potential-transaction-rule-matches matches)]}))
|
||||
[::edit/editing which (:potential-payment-matches matches) (:potential-autopay-invoices-matches matches) (:potential-unpaid-invoices-matches matches) (:potential-transaction-rule-matches matches)]}))
|
||||
|
||||
(re-frame/reg-event-fx
|
||||
::editing-matches-failed
|
||||
@@ -41,6 +41,9 @@
|
||||
{:transaction_id (:id which)}
|
||||
[:id :memo :check-number [:vendor [:name]]]]}
|
||||
{:query/data [:potential-autopay-invoices-matches
|
||||
{:transaction_id (:id which)}
|
||||
[:id :invoice-number :total :date :scheduled-payment [:vendor [:name]]]]}
|
||||
{:query/data [:potential-unpaid-invoices-matches
|
||||
{:transaction_id (:id which)}
|
||||
[:id :invoice-number :total :date :scheduled-payment [:vendor [:name]]]]}]
|
||||
(when @(re-frame/subscribe [::subs/is-admin?])
|
||||
|
||||
Reference in New Issue
Block a user