adding invoices works correctly again.

This commit is contained in:
Bryce Covert
2018-08-16 19:36:50 -07:00
parent 1208f972ef
commit bcb839aaa8
7 changed files with 123 additions and 79 deletions

View File

@@ -11,18 +11,26 @@
(update-in [:query :where] conj where))]
(reduce #(update-in %1 [:query :where] conj %2) query rest)))
(def default-read '(pull ?e [*
{:invoice/client [:client/name :db/id]}
{:invoice/vendor [:vendor/name :db/id]}
{:invoice/status [:db/ident]}
{:invoice-payment/_invoice [* {:invoice-payment/payment [*]}]}]))
(defn <-datomic [x]
(->> x
(map first)
(map #(update % :invoice/date c/from-date))
(map #(update % :invoice/status :db/ident))
(map #(rename-keys % {:invoice-payment/_invoice :invoice/payments}))))
(defn raw-graphql [args]
(->> (d/query
(cond-> (doto {:query {:find ['(pull ?e [*
{:invoice/client [:client/name :db/id]}
{:invoice/vendor [:vendor/name :db/id]}
{:invoice/status [:db/ident]}
{:invoice-payment/_invoice [* {:invoice-payment/payment [*]}]}])]
:in ['$]
:where ['[?e :invoice/original-id]
]}
:args [(d/db (d/connect uri))]}
println)
(cond-> {:query {:find [default-read]
:in ['$]
:where ['[?e :invoice/invoice-number]]}
:args [(d/db (d/connect uri))]}
(:client-id args) (add-arg '?client-id (cond-> (:client-id args)
(string? (:client-id args))
@@ -34,13 +42,7 @@
'[?c :client/original-id ?original-id])
(:status args) (add-arg '?status (keyword "invoice-status" (:status args))
'[?e :invoice/status ?status])))
(map first)
(map #(update % :invoice/date c/from-date))
(map #(update % :invoice/status :db/ident))
(map #(rename-keys % {:invoice-payment/_invoice :invoice/payments}))
#_(map #(update % :transaction/post-date c/from-date))))
(<-datomic)))
(defn sort-fn [args]
(cond
@@ -65,3 +67,23 @@
(->> (raw-graphql args)
(count)))
(defn get-by-id [id]
(->>
(d/query (-> {:query {:find [default-read]
:in ['$]
:where []}
:args [(d/db (d/connect uri))]}
(add-arg '?e (cond-> id (string? id) Long/parseLong) ['?e])))
(<-datomic)
(first)))
(defn find-conflicting [{:keys [:invoice/invoice-number :invoice/vendor :invoice/client]}]
(->> (d/query
(cond-> {:query {:find [default-read]
:in ['$ '?invoice-number '?vendor '?client]
:where ['[?e :invoice/invoice-number ?invoice-number]
'[?e :invoice/vendor ?vendor]
'[?e :invoice/client ?client]]}
:args [(d/db (d/connect uri)) invoice-number (Long/parseLong vendor) (Long/parseLong client)]}))
(<-datomic)))

View File

@@ -14,3 +14,19 @@
(map (fn [ba]
(update ba :bank-account/type :db/ident ))
bas)))))))
(defn get-by-id [id]
(->> (d/q '[:find (pull ?e [*])
:in $ ?e
:where [?e]]
(d/db (d/connect uri))
(Long/parseLong id))
(map first)
(first)
#_(map (fn [c]
(update c :client/bank-accounts
(fn [bas]
(map (fn [ba]
(update ba :bank-account/type :db/ident ))
bas)))))))

View File

@@ -273,12 +273,12 @@
:amount {:type 'String}}}
:add_invoice
{:fields {:id {:type 'Int}
{:fields {:id {:type 'String}
:invoice_number {:type 'String}
:location {:type 'String}
:date {:type 'String}
:company_id {:type 'Int}
:vendor_id {:type 'Int}
:client_id {:type 'String}
:vendor_id {:type 'String}
:vendor_name {:type 'String}
:total {:type 'Float}}}
@@ -316,9 +316,9 @@
:void_invoice {:type :invoice
:args {:invoice_id {:type 'Int}}
:resolve :mutation/void-invoice}
:void_check {:type :payment
:void_payment {:type :payment
:args {:payment_id {:type 'String}}
:resolve :mutation/void-check}
:resolve :mutation/void-payment}
:edit_expense_accounts {:type :invoice
:args {:invoice_id {:type 'Int}
:expense_accounts {:type '(list :edit_expense_account)}}
@@ -483,7 +483,7 @@
:mutation/add-invoice gq-invoices/add-invoice
:mutation/edit-invoice gq-invoices/edit-invoice
:mutation/void-invoice gq-invoices/void-invoice
:mutation/void-check gq-checks/void-check
:mutation/void-payment gq-checks/void-check
:mutation/edit-expense-accounts gq-invoices/edit-expense-accounts
:get-vendor get-vendor
:get-expense-account expense-accounts/get-expense-account

View File

@@ -2,40 +2,48 @@
(:require [auto-ap.graphql.utils :refer [->graphql assert-can-see-company]]
[auto-ap.db.invoices :as invoices]
[auto-ap.db.vendors :as vendors]
[auto-ap.datomic.vendors :as d-vendors]
[auto-ap.datomic.invoices :as d-invoices]
[auto-ap.db.companies :as companies]
[auto-ap.db.invoices-expense-accounts :as invoices-expense-accounts]
[auto-ap.expense-accounts :as expense-accounts]
[auto-ap.time :refer [parse iso-date]]))
[auto-ap.time :refer [parse iso-date]]
[datomic.api :as d]
[auto-ap.datomic :refer [uri]]
[clj-time.coerce :as coerce]))
(defn -create-or-get-vendor [vendor-id vendor-name]
(if vendor-id
(vendors/get-by-id vendor-id)
(vendors/insert {:name vendor-name :default-expense-account 0})))
(defn add-invoice [context {{:keys [total invoice_number location company_id vendor_id vendor_name date] :as in} :invoice} value]
(when (seq (invoices/find-conflicting {:invoice-number invoice_number
:vendor-id vendor_id
:company-id company_id}))
(defn add-invoice [context {{:keys [total invoice_number location client_id vendor_id vendor_name date] :as in} :invoice} value]
(when (seq (d-invoices/find-conflicting {:invoice/invoice-number invoice_number
:invoice/vendor vendor_id
:invoice/client client_id}))
(throw (ex-info (str "Invoice '" invoice_number "' already exists.") {:invoice-number invoice_number})))
(let [vendor (-create-or-get-vendor vendor_id vendor_name)
_ (assert-can-see-company (:id context) company_id)
_ (when-not (:default-expense-account vendor)
(throw (ex-info (str "Vendor '" (:name vendor) "' does not have a default expense acount.") {:vendor-id vendor_id} )))
company (companies/get-by-id company_id)
[invoice] (invoices/insert-multi! [{:invoice-number invoice_number
:company-id company_id
:vendor-id (:id vendor)
:total total
:outstanding-balance total
:status "unpaid"
:imported true
:date (parse date iso-date)}])]
(invoices-expense-accounts/replace-for-invoice
(:id invoice) [{:expense-account-id (:default-expense-account vendor)
:location (get-in expense-accounts/expense-accounts [(:default-expense-account vendor) :location] location)
:amount total}] )
(-> invoice
(let [_ (assert-can-see-company (:id context) client_id)
vendor (d-vendors/get-by-id vendor_id)
expense-account-id (:vendor/default-expense-account vendor)
_ (when-not expense-account-id
(throw (ex-info (str "Vendor '" (:vendor/name vendor) "' does not have a default expense acount.") {:vendor-id vendor_id} )))
transaction [{:db/id "invoice"
:invoice/invoice-number invoice_number
:invoice/client (Long/parseLong client_id)
:invoice/vendor (Long/parseLong vendor_id)
:invoice/total total
:invoice/outstanding-balance total
:invoice/status :invoice-status/unpaid
:invoice/date (coerce/to-date date)
:invoice/expense-accounts [{:invoice-expense-account/expense-account-id expense-account-id
:invoice-expense-account/location (get-in expense-accounts/expense-accounts [expense-account-id :location] location)
:invoice-expense-account/amount total}]}]
transaction-result @(d/transact (d/connect uri) transaction)
]
(-> (d-invoices/get-by-id (get-in transaction-result [:tempids "invoice"]))
(->graphql))))
@@ -66,9 +74,7 @@
(->graphql))))
(defn get-invoices-expense-accounts [context args value]
(->graphql
(invoices-expense-accounts/get-for-invoice (:id value))))
(defn edit-expense-accounts [context args value]
(assert-can-see-company (:id context) (:company-id (invoices/get-by-id (:invoice_id args))))

View File

@@ -2,14 +2,14 @@
(:require [clojure.spec.alpha :as s]
[auto-ap.entities.shared :as shared]))
(s/def ::vendor-id int?)
(s/def ::vendor-id string?)
(s/def ::vendor-name string?)
(s/def ::company-id int?)
(s/def ::client-id string?)
(s/def ::invoice-number ::shared/required-identifier)
(s/def ::date ::shared/date)
(s/def ::total ::shared/money)
(s/def ::invoice (s/keys :req-un [::company-id
(s/def ::invoice (s/keys :req-un [::client-id
::invoice-number
::date
::vendor-id

View File

@@ -17,9 +17,9 @@
(re-frame/reg-sub
::check-page
::payment-page
(fn [db]
(-> db ::check-page)))
(-> db ::payment-page)))
(re-frame/reg-sub
::params
@@ -44,33 +44,33 @@
(re-frame/reg-event-fx
::void-check
(fn [{:keys [db]} [_ check]]
(fn [{:keys [db]} [_ payment]]
{:graphql
{:token (-> db :user)
:query-obj {:venia/operation {:operation/type :mutation
:operation/name "VoidCheck"}
:operation/name "VoidPayment"}
:venia/queries [{:query/data [:void-check
{:payment-id (:id check)}
:venia/queries [{:query/data [:void-payment
{:payment-id (:id payment)}
[:id :status :amount :check_number :s3_url :date [:vendor [:name :id]] [:client [:name :id]]]]}]}
:on-success [::check-voided]}}))
:on-success [::payment-voided]}}))
(re-frame/reg-event-db
::check-voided
(fn [db [_ {:keys [void-check]}]]
::payment-voided
(fn [db [_ {:keys [void-payment]}]]
(-> db
(update-in [::check-page :payments] (fn [checks]
(update-in [::payment-page :payments] (fn [payments]
(mapv (fn [c]
(if (= (:id c) (:id void-check))
(assoc void-check :class "live-removed")
(if (= (:id c) (:id void-payment))
(assoc void-payment :class "live-removed")
c))
checks))))))
payments))))))
(re-frame/reg-event-db
::received
(fn [db [_ data]]
(-> db
(assoc ::check-page (first (:payment-page data)))
(assoc ::payment-page (first (:payment-page data)))
(assoc-in [:status :loading] false))))
(re-frame/reg-event-fx
@@ -78,15 +78,15 @@
(fn [cofx [_ params]]
{:dispatch [::params-change @(re-frame/subscribe [::params])]}))
(defn check-table [{:keys [id check-page status on-params-change vendors params check-boxes checked on-check-changed expense-event]}]
(defn check-table [{:keys [id payment-page status on-params-change vendors params check-boxes checked on-check-changed expense-event]}]
(let [state (reagent/atom (or @params {}))
selected-company @(re-frame/subscribe [::subs/company])
opc (fn [p]
(swap! state merge p)
(on-params-change p))]
(fn [{:keys [id check-page status on-params-change vendors checked]}]
(fn [{:keys [id payment-page status on-params-change vendors checked]}]
(let [{:keys [sort-by asc]} @state
{:keys [payments start end count total]} @check-page
{:keys [payments start end count total]} @payment-page
selected-company @(re-frame/subscribe [::subs/company])
percentage-size (if selected-company "50%" "33%")]
[:div
@@ -147,7 +147,7 @@
[:tr
[:td {:col-span 5}
[:i.fa.fa-spin.fa-spinner]]]
(for [{:keys [client s3-url payments type check-number date amount id vendor status] :as i} (:payments @check-page)]
(for [{:keys [client s3-url payments type check-number date amount id vendor status] :as i} (:payments @payment-page)]
^{:key id}
[:tr {:class (:class i)}
@@ -179,9 +179,9 @@
(let [current-company @(re-frame/subscribe [::subs/company])]
[:div
[:h1.title "Checks"]
[check-table {:id :checks
[check-table {:id :payments
:params (re-frame/subscribe [::params])
:check-page (re-frame/subscribe [::check-page])
:payment-page (re-frame/subscribe [::payment-page])
:status (re-frame/subscribe [::subs/status])
:on-params-change (fn [params]
(re-frame/dispatch [::params-change params]))}]]))

View File

@@ -237,7 +237,7 @@
::new-invoice
(fn [{:keys [db]} _]
{:dispatch [::events/modal-status ::new-invoice {:visible? true}]
:db (assoc-in db [::new-invoice] {:company-id (:id @(re-frame/subscribe [::subs/company]))
:db (assoc-in db [::new-invoice] {:client-id (:id @(re-frame/subscribe [::subs/company]))
:date (date->str (c/now) standard)
:location (first (:locations @(re-frame/subscribe [::subs/company])))})}))
@@ -261,7 +261,7 @@
:venia/queries [{:query/data [:add-invoice
{:invoice new-invoice}
[:id :total :outstanding-balance :date :invoice-number
[:company [:id :name :locations]]
[:client [:id :name :locations]]
[:vendor [:id :name]]
[:expense_accounts [:amount :id :expense_account_id
:location
@@ -645,7 +645,7 @@
(defn new-invoice-modal []
(let [data @(re-frame/subscribe [::new-invoice])
change-event [::events/change-form [::new-invoice]]
locations (get-in @(re-frame/subscribe [::subs/companies-by-id]) [(:company-id data) :locations])
locations (get-in @(re-frame/subscribe [::subs/companies-by-id]) [(:client-id data) :locations])
should-select-location? (and locations
(> (count locations) 1))]
[action-modal {:id ::new-invoice
@@ -656,13 +656,13 @@
(when-not @(re-frame/subscribe [::subs/company])
[horizontal-field
[:label.label "Company"]
[:label.label "Client"]
[bind-field
[typeahead {:matches (map (fn [x] [(:id x) (:name x)]) @(re-frame/subscribe [::subs/companies]))
:type "typeahead"
:field [:company-id]
:field [:client-id]
:event [::change-new-invoice-company [::new-invoice]]
:spec ::invoice/company-id
:spec ::invoice/client-id
:subscription data}]]])
(when should-select-location?
[horizontal-field