diff --git a/dev-resources/add-manual-yodlee.tsv b/dev-resources/add-manual-yodlee.tsv index 5d1823a8..a72aa22a 100644 --- a/dev-resources/add-manual-yodlee.tsv +++ b/dev-resources/add-manual-yodlee.tsv @@ -1,2 +1,2 @@ - posted 12/12/2020 RESTAURANT DEPOT RESTAURANT DEPOT -5.42 CBC-1 CBC + posted 12/12/2020 RESTAURANT DEPOT RESTAURANT DEPOT -5.42 NGAK-1 NGAK diff --git a/docker-compose.dev.yml b/docker-compose.dev.yml index 20b0d93b..52e826ab 100644 --- a/docker-compose.dev.yml +++ b/docker-compose.dev.yml @@ -11,9 +11,11 @@ services: # - ./data/var/run/docker.sock:/tmp/docker.sock:ro - ./data/opt/integreat/dev/usr/share/nginx/html:/usr/share/nginx/html database: + restart: "always" ports: - "5432:5432" datomic-transactor: + restart: "always" environment: - DATOMIC_PORT=4334 - XMS=-Xms4g diff --git a/src/clj/auto_ap/graphql.clj b/src/clj/auto_ap/graphql.clj index 72485bdd..5f97f478 100644 --- a/src/clj/auto_ap/graphql.clj +++ b/src/clj/auto_ap/graphql.clj @@ -982,6 +982,11 @@ :autopay_invoice_ids {:type '(list :id)}} :resolve :mutation/match-transaction-autopay-invoices} + :match_transaction_unpaid_invoices {:type :transaction + :args {:transaction_id {:type :id} + :unpaid_invoice_ids {:type '(list :id)}} + :resolve :mutation/match-transaction-unpaid-invoices} + :match_transaction_rules {:type '(list :transaction) :args {:transaction_ids {:type '(list :id)} :all {:type 'Boolean} @@ -1276,6 +1281,7 @@ :run-transaction-rule gq-transaction-rules/run-transaction-rule :mutation/match-transaction gq-transactions/match-transaction :mutation/match-transaction-autopay-invoices gq-transactions/match-transaction-autopay-invoices + :mutation/match-transaction-unpaid-invoices gq-transactions/match-transaction-unpaid-invoices :mutation/match-transaction-rules gq-transactions/match-transaction-rules :mutation/edit-client gq-clients/edit-client :mutation/upsert-vendor gq-vendors/upsert-vendor diff --git a/src/clj/auto_ap/graphql/transactions.clj b/src/clj/auto_ap/graphql/transactions.clj index d30e3988..2cf6cbf3 100644 --- a/src/clj/auto_ap/graphql/transactions.clj +++ b/src/clj/auto_ap/graphql/transactions.clj @@ -333,6 +333,45 @@ approval-status->graphql ->graphql))) +(defn match-transaction-unpaid-invoices [context {:keys [transaction_id unpaid_invoice_ids]} value] + (let [_ (assert-admin (:id context)) + transaction (d-transactions/get-by-id transaction_id) + _ (assert-can-see-client (:id context) (:transaction/client transaction) ) + db (d/db conn) + invoice-clients (set (map (comp :db/id :invoice/client #(d/entity db %)) unpaid_invoice_ids)) + invoice-amount (reduce + 0.0 (map (comp :invoice/total #(d/entity db %)) unpaid_invoice_ids))] + (when (or (> (count invoice-clients) 1) + (not= (:db/id (:transaction/client transaction)) + (first invoice-clients))) + (throw (ex-info "Clients don't match" {:validation-error "Invoice(s) and transaction client do not match." + :invoice-clients (str invoice-clients)}))) + + (when-not (dollars= (- (:transaction/amount transaction)) + invoice-amount) + (throw (ex-info "Amounts don't match" {:validation-error "Amounts don't match"}))) + #_(log/info [#_(select-keys (d/entity db transaction_id) #{:transaction/amount :db/id})] + (->> autopay_invoice_ids + (map (fn [id] + (let [entity (d/entity db id)] + [(-> entity :invoice/vendor :db/id) + (-> entity :db/id) + (-> entity :invoice/total)]))))) + (let [payment-tx (import/add-new-payment [(select-keys (d/entity db transaction_id) #{:transaction/amount :transaction/date :db/id})] + (map (fn [id] + (let [entity (d/entity db id)] + [(-> entity :invoice/vendor :db/id) + (-> entity :db/id) + (-> entity :invoice/total)])) + unpaid_invoice_ids) + (:db/id (:transaction/bank-account transaction)) + (:db/id (:transaction/client transaction)))] + (log/info "Adding a new payment" payment-tx) + @(d/transact conn payment-tx)) + + (-> (d-transactions/get-by-id transaction_id) + approval-status->graphql + ->graphql))) + (defn match-transaction-rules [context {:keys [transaction_ids transaction_rule_id all]} value] (let [_ (assert-admin (:id context)) transaction_ids (if all diff --git a/src/clj/auto_ap/yodlee/import.clj b/src/clj/auto_ap/yodlee/import.clj index 0d5efdb0..fda747a2 100644 --- a/src/clj/auto_ap/yodlee/import.clj +++ b/src/clj/auto_ap/yodlee/import.clj @@ -217,6 +217,7 @@ :location "A" :amount (Math/abs (double amount))}])) + ;; temporarily removed to automatically match autopaid invoices #_(and (not existing-check) (seq autopay-invoices-matches)) #_(add-new-payment autopay-invoices-matches bank-account-id client-id) diff --git a/src/cljs/auto_ap/views/pages/transactions/form.cljs b/src/cljs/auto_ap/views/pages/transactions/form.cljs index 832e2743..54389a64 100644 --- a/src/cljs/auto_ap/views/pages/transactions/form.cljs +++ b/src/cljs/auto_ap/views/pages/transactions/form.cljs @@ -130,6 +130,23 @@ :on-success (fn [result] [::edited (:match-transaction-autopay-invoices result)])}})) +(re-frame/reg-event-fx + ::matching-unpaid-invoices + [with-user (forms/triggers-loading ::form) (forms/in-form ::form)] + (fn [{{{:keys [id]} :data} :db user :user} [_ invoice-ids]] + {:graphql + {:token user + :query-obj {:venia/operation {:operation/type :mutation + :operation/name "MatchTransactionUnpaidInvoices"} + :venia/queries [{:query/data [:match-transaction-unpaid-invoices + {:transaction_id id + :unpaid-invoice-ids invoice-ids} + transaction-read]}]} + :owns-state {:multi ::matching + :which [:unpaid-invoices invoice-ids]} + :on-success (fn [result] + [::edited (:match-transaction-unpaid-invoices result)])}})) + (re-frame/reg-event-fx ::matching-rule [with-user (forms/triggers-loading ::form) (forms/in-form ::form)] diff --git a/test/clj/auto_ap/integration/yodlee/import.clj b/test/clj/auto_ap/integration/yodlee/import.clj index 7df6ff27..6249552b 100644 --- a/test/clj/auto_ap/integration/yodlee/import.clj +++ b/test/clj/auto_ap/integration/yodlee/import.clj @@ -135,7 +135,7 @@ (t/is (= nil (:transaction/payment result))))))) - (t/testing "Auto-pay Invoices" + #_(t/testing "Auto-pay Invoices" (t/testing "Should match paid invoice that doesn't have a payment yet" (let [{:strs [bank-account-id client-id invoice1-id invoice2-id vendor-id]} (->> [#:invoice {:status :invoice-status/paid :vendor "vendor-id"