avoids duplicate invoices atomic, prevents query that causes warnings.

This commit is contained in:
2021-11-17 21:50:12 -08:00
parent f345788284
commit fe48373943
4 changed files with 79 additions and 37 deletions

View File

@@ -79,6 +79,24 @@
(seq vs) (conj {:db/id e (seq vs) (conj {:db/id e
a vs})))})}]]) a vs})))})}]])
(defn propose-invoice-fn [conn]
[[{:db/ident :propose-invoice
:db/doc "Adds an invoice if it's not found"
:db/fn (d/function '{:lang "clojure"
:params [db invoice]
:code (let [existing? (boolean (seq (d/query {:query {:find ['?i]
:in ['$ '?invoice-number '?client '?vendor]
:where ['[?i :invoice/invoice-number ?invoice-number]
'[?i :invoice/client ?client]
'[?i :invoice/vendor ?vendor]
'(not [?i :invoice/status :invoice-status/voided])
]}
:args [db (:invoice/invoice-number invoice) (:invoice/client invoice) (:invoice/vendor invoice)]})))]
(if existing?
[]
[invoice]))})}]])
(defn add-include-in-reports [conn] (defn add-include-in-reports [conn]
(let [existing-accounts (->> (d/query {:query {:find ['?e] (let [existing-accounts (->> (d/query {:query {:find ['?e]
:in ['$] :in ['$]
@@ -335,7 +353,13 @@
:db/cardinality :db.cardinality/one}]]} :db/cardinality :db.cardinality/one}]]}
:auto-ap/add-power-user-schema {:txes [[{:db/ident :user-role/power-user}]]} :auto-ap/add-power-user-schema {:txes [[{:db/ident :user-role/power-user}]]}
:auto-ap/add-transaction-date-index {:txes [[{:db/ident :transaction/date :auto-ap/add-transaction-date-index {:txes [[{:db/ident :transaction/date
:db/index true}]]}} :db/index true}]]}
:auto-ap/add-invoice-index {:txes [[{:db/ident :invoice/invoice-number
:db/index true}]]
:depends-on [:auto-ap/base-schema]}
:auto-ap/add-propose-invoice {:txes-fn `propose-invoice-fn
:depends-on [:auto-ap/base-schema]}}

View File

@@ -182,7 +182,7 @@
:status :payment-status/cleared :status :payment-status/cleared
:date (:invoice/date invoice)})} :date (:invoice/date invoice)})}
)] )]
[invoice payment]))) [[:propose-invoice invoice] payment])))
(filter identity) (filter identity)
(map remove-nils) (map remove-nils)
)) ))
@@ -280,26 +280,26 @@
result result
:else :else
(conj result (cond-> (remove-nils #:invoice {:invoice/client (:db/id matching-client) (conj result [:propose-invoice (cond-> (remove-nils #:invoice {:invoice/client (:db/id matching-client)
:invoice/client-identifier customer-identifier :invoice/client-identifier customer-identifier
:invoice/vendor (:db/id matching-vendor) :invoice/vendor (:db/id matching-vendor)
:invoice/invoice-number invoice-number :invoice/invoice-number invoice-number
:invoice/total (Double/parseDouble total) :invoice/total (Double/parseDouble total)
:invoice/date (to-date date) :invoice/date (to-date date)
:invoice/import-status :import-status/pending :invoice/import-status :import-status/pending
:invoice/outstanding-balance (or existing-outstanding-balance (Double/parseDouble total)) :invoice/outstanding-balance (or existing-outstanding-balance (Double/parseDouble total))
:invoice/status (or existing-status :invoice-status/unpaid) :invoice/status (or existing-status :invoice-status/unpaid)
:invoice/expense-accounts (when-not existing-id [#:invoice-expense-account {:account (d-vendors/account-for-client-id matching-vendor (:db/id matching-client)) :invoice/expense-accounts (when-not existing-id [#:invoice-expense-account {:account (d-vendors/account-for-client-id matching-vendor (:db/id matching-client))
:location matching-location :location matching-location
:amount (Double/parseDouble total)}]) :amount (Double/parseDouble total)}])
:db/id existing-id :db/id existing-id
}) })
(:vendor/terms matching-vendor) (assoc :invoice/due (coerce/to-date (:vendor/terms matching-vendor) (assoc :invoice/due (coerce/to-date
(time/plus date (time/days (d-vendors/terms-for-client-id matching-vendor (:db/id matching-client)))))) (time/plus date (time/days (d-vendors/terms-for-client-id matching-vendor (:db/id matching-client))))))
(boolean (automatically-paid-for (:db/id matching-client))) (assoc :invoice/scheduled-payment (coerce/to-date (boolean (automatically-paid-for (:db/id matching-client))) (assoc :invoice/scheduled-payment (coerce/to-date
(time/plus date (time/days (d-vendors/terms-for-client-id matching-vendor (:db/id matching-client)))))) (time/plus date (time/days (d-vendors/terms-for-client-id matching-vendor (:db/id matching-client))))))
schedule-payment-dom (assoc :invoice/scheduled-payment (to-date schedule-payment-dom (assoc :invoice/scheduled-payment (to-date
(next-dom date schedule-payment-dom)))))) (next-dom date schedule-payment-dom))))]))
)) ))
[] []
imports)] imports)]

View File

@@ -8,7 +8,7 @@
[auto-ap.views.pages.transactions.form :as edit] [auto-ap.views.pages.transactions.form :as edit]
[auto-ap.views.utils [auto-ap.views.utils
:refer :refer
[action-cell-width date->str dispatch-event dispatch-event-with-propagation nf pretty]] [action-cell-width date->str dispatch-event dispatch-event-with-propagation nf pretty with-role]]
[goog.string :as gstring] [goog.string :as gstring]
[re-frame.core :as re-frame] [re-frame.core :as re-frame]
[auto-ap.views.components.buttons :as buttons] [auto-ap.views.components.buttons :as buttons]
@@ -32,24 +32,29 @@
(re-frame/reg-event-fx (re-frame/reg-event-fx
::intend-to-edit ::intend-to-edit
(fn [{:keys [db]} [_ which]] [with-role]
(fn [{:keys [db role]} [_ which]]
{:graphql {:graphql
{:token (-> db :user) {:token (-> db :user)
:owns-state {:multi ::edits :owns-state {:multi ::edits
:which (:id which)} :which (:id which)}
:query-obj {:venia/queries (into [{:query/data [:potential-payment-matches :query-obj {:venia/queries
{:transaction_id (:id which)} (cond-> [{:query/data [:potential-payment-matches
[:id :memo :check-number [:vendor [:name]]]]} {:transaction_id (:id which)}
{:query/data [:potential-autopay-invoices-matches [:id :memo :check-number [:vendor [:name]]]]}]
{:transaction_id (:id which)} (or (= "admin" role)
[:id :invoice-number :total :date :scheduled-payment [:vendor [:name]]]]} (= "power-user" role))
{:query/data [:potential-unpaid-invoices-matches
{:transaction_id (:id which)} (into [{:query/data [:potential-autopay-invoices-matches
[:id :invoice-number :total :date :scheduled-payment [:vendor [:name]]]]}] {:transaction_id (:id which)}
(when @(re-frame/subscribe [::subs/is-admin?]) [:id :invoice-number :total :date :scheduled-payment [:vendor [:name]]]]}
[{:query/data [:potential-transaction-rule-matches {:query/data [:potential-unpaid-invoices-matches
{:transaction_id (:id which)} {:transaction_id (:id which)}
[:id :note]]}]))} [:id :invoice-number :total :date :scheduled-payment [:vendor [:name]]]]}])
(= "admin" role)
(into [{:query/data [:potential-transaction-rule-matches
{:transaction_id (:id which)}
[:id :note]]}]))}
:on-success [::editing-matches-found which] :on-success [::editing-matches-found which]
:on-error [::editing-matches-failed which]}})) :on-error [::editing-matches-failed which]}}))

View File

@@ -466,6 +466,19 @@
(-> context (-> context
(assoc-in [:coeffects :user] (get-in context [:coeffects :db :user])))))) (assoc-in [:coeffects :user] (get-in context [:coeffects :db :user]))))))
(def with-role
(re-frame/->interceptor
:id :with-role
:before (fn [context]
(-> context
(assoc-in [:coeffects :role] (-> (get-in context [:coeffects :db :user])
(str/split #"\.")
second
(base64/decodeString )
(#(.parse js/JSON % ))
(js->clj :keywordize-keys true)
:user/role))))))
(def with-is-admin? (def with-is-admin?
(re-frame/->interceptor (re-frame/->interceptor
:id :with-is-admin? :id :with-is-admin?