merged.
This commit is contained in:
@@ -1,19 +1,35 @@
|
||||
(ns auto-ap.datomic.accounts
|
||||
(:require [datomic.api :as d]
|
||||
[auto-ap.graphql.utils :refer [->graphql]]
|
||||
[auto-ap.datomic :refer [uri merge-query]]))
|
||||
(:require
|
||||
[auto-ap.datomic
|
||||
:refer [add-sorter-fields apply-pagination apply-sort-3 conn merge-query uri]]
|
||||
[clojure.string :as str]
|
||||
[datomic.api :as d]
|
||||
[clojure.tools.logging :as log]))
|
||||
|
||||
(defn <-datomic [a]
|
||||
(update a :account/applicability :db/ident))
|
||||
|
||||
(def default-read ['* {:account/type [:db/ident :db/id]
|
||||
:account/applicability [:db/ident :db/id]
|
||||
:account/client-overrides [:db/id
|
||||
:account-client-override/name
|
||||
{:account-client-override/client [:db/id :client/name]}]}])
|
||||
|
||||
(defn clientize [a client]
|
||||
(if-let [override-name (->> a
|
||||
:account/client-overrides
|
||||
(filter #(= client
|
||||
(:db/id (:account-client-override/client %))))
|
||||
first
|
||||
:account-client-override/name)]
|
||||
(assoc a :account/name override-name)
|
||||
a))
|
||||
|
||||
(defn get-accounts
|
||||
([]
|
||||
(get-accounts {}))
|
||||
([args]
|
||||
(let [query (cond-> {:query {:find ['(pull ?e [* {:account/type [:db/ident :db/id]
|
||||
:account/applicability [:db/ident :db/id]
|
||||
:account/client-overrides [:db/id
|
||||
:account-client-override/name
|
||||
{:account-client-override/client [:db/id :client/name]}]}])]
|
||||
(let [query (cond-> {:query {:find [(list 'pull '?e default-read)]
|
||||
:in ['$]
|
||||
:where [['?e :account/name]]}
|
||||
:args [(d/db (d/connect uri))]}
|
||||
@@ -26,11 +42,7 @@
|
||||
(map <-datomic)))))
|
||||
|
||||
(defn get-by-id [id]
|
||||
(let [query {:query {:find ['(pull ?e [* {:account/type [:db/ident :db/id]
|
||||
:account/applicability [:db/ident :db/id]
|
||||
:account/client-overrides [:db/id
|
||||
:account-client-override/name
|
||||
{:account-client-override/client [:db/id :client/name]}]}])]
|
||||
(let [query {:query {:find [(list 'pull '?e default-read)]
|
||||
:in ['$ '?e]}
|
||||
:args [(d/db (d/connect uri) ) id]}]
|
||||
(->>
|
||||
@@ -39,6 +51,34 @@
|
||||
(map <-datomic)
|
||||
first)))
|
||||
|
||||
(defn get-for-vendor [vendor-id client-id]
|
||||
(if client-id
|
||||
(->>
|
||||
(d/q [:find (list 'pull '?e default-read)
|
||||
:in '$ '?v '?c
|
||||
:where '(or-join [?v ?c ?e]
|
||||
(and [?v :vendor/account-overrides ?ao]
|
||||
[?ao :vendor-account-override/client ?c]
|
||||
[?ao :vendor-account-override/account ?e])
|
||||
(and [?v :vendor/account-overrides ?ao]
|
||||
(not [?ao vendor-account-override/client ?c])
|
||||
[?v :vendor/default-account ?e])
|
||||
(and (not [?v :vendor/account-overrides])
|
||||
[?v :vendor/default-account ?e]))]
|
||||
|
||||
(d/db conn )
|
||||
vendor-id
|
||||
client-id)
|
||||
(map first)
|
||||
(map <-datomic)
|
||||
first)
|
||||
(d/q [:find (list 'pull '?e default-read)
|
||||
:in '$ '?v
|
||||
:where '[?v :vendor/default-account ?e]]
|
||||
|
||||
(d/db conn )
|
||||
vendor-id)))
|
||||
|
||||
(defn get-account-by-numeric-code-and-sets [numeric-code sets]
|
||||
(let [query (cond-> {:query {:find ['(pull ?e [* {:account/type [:db/ident :db/id]}])]
|
||||
:in ['$ '?numeric-code]
|
||||
@@ -50,4 +90,50 @@
|
||||
(map <-datomic)
|
||||
(first))))
|
||||
|
||||
#_(get-account-by-numeric-code-and-sets 5110 nil)
|
||||
(defn raw-graphql-ids [db args]
|
||||
(println args)
|
||||
(let [query (cond-> {:query {:find []
|
||||
:in ['$]
|
||||
:where []}
|
||||
:args [db]}
|
||||
(:sort args) (add-sorter-fields {"name" ['[?e :account/name ?sort-name]]}
|
||||
args)
|
||||
|
||||
(:numeric-code args)
|
||||
(merge-query {:query {:in ['?numeric-code]
|
||||
:where ['[?e :account/numeric-code ?numeric-code]]}
|
||||
:args [(:numeric-code args)]})
|
||||
|
||||
(not (str/blank? (:name-like args)))
|
||||
(merge-query {:query {:in ['?name-like]
|
||||
:where ['[?e :account/name ?n]
|
||||
'[(re-find ?name-like ?n)]]}
|
||||
:args [(re-pattern (str "(?i)" (:name-like args)))]})
|
||||
|
||||
true
|
||||
(merge-query {:query {:find ['?sort-default '?e ]
|
||||
:where ['[?e :account/name]
|
||||
'[?e :account/numeric-code ?sort-default]]}}))]
|
||||
|
||||
|
||||
(cond->> query
|
||||
true (d/query)
|
||||
true (apply-sort-3 args)
|
||||
true (apply-pagination args))))
|
||||
|
||||
|
||||
(defn graphql-results [ids db args]
|
||||
(let [results (->> (d/pull-many db default-read ids)
|
||||
(group-by :db/id))
|
||||
accounts (->> ids
|
||||
(map results)
|
||||
(map first)
|
||||
(map <-datomic))]
|
||||
accounts))
|
||||
|
||||
(defn get-graphql [args]
|
||||
(log/info "ARGS" args)
|
||||
(let [db (d/db conn)
|
||||
{ids-to-retrieve :ids matching-count :count} (raw-graphql-ids db args)]
|
||||
[(->> (graphql-results ids-to-retrieve db args))
|
||||
matching-count]))
|
||||
|
||||
@@ -6,13 +6,18 @@
|
||||
[clj-time.coerce :as coerce]
|
||||
[auto-ap.time-utils :refer [next-dom]]
|
||||
[clj-time.core :as time]
|
||||
[auto-ap.datomic.vendors :as d-vendors]))
|
||||
[auto-ap.datomic.vendors :as d-vendors]
|
||||
[clojure.tools.logging :as log]
|
||||
[auto-ap.datomic.accounts :as d-accounts]))
|
||||
|
||||
(def default-read '[*
|
||||
{:invoice/client [:client/name :db/id :client/locations :client/code]}
|
||||
{:invoice/vendor [* {:vendor/address [*]}]}
|
||||
{:invoice/status [:db/ident]}
|
||||
{:invoice/expense-accounts [* {:invoice-expense-account/account [*]}]}
|
||||
{:invoice/expense-accounts [* {:invoice-expense-account/account [:account/name :db/id
|
||||
:account/location
|
||||
{:account/client-overrides [:account-client-override/name
|
||||
{:account-client-override/client [:db/id]}]}]}]}
|
||||
{:invoice-payment/_invoice [* {:invoice-payment/payment [* {:payment/status [*]}
|
||||
{:payment/bank-account [*]}
|
||||
{:transaction/_payment [*]}]}]}])
|
||||
@@ -23,6 +28,10 @@
|
||||
(update :invoice/due coerce/from-date)
|
||||
(update :invoice/scheduled-payment coerce/from-date)
|
||||
(update :invoice/status :db/ident)
|
||||
(update :invoice/expense-accounts (fn [eas]
|
||||
(map
|
||||
#(update % :invoice-expense-account/account d-accounts/clientize (:db/id (:invoice/client x)))
|
||||
eas)))
|
||||
(rename-keys {:invoice-payment/_invoice :invoice/payments})))
|
||||
|
||||
(defn raw-graphql-ids
|
||||
@@ -303,6 +312,7 @@
|
||||
|
||||
schedule-payment-dom
|
||||
(-> date
|
||||
coerce/to-date-time
|
||||
(next-dom schedule-payment-dom)
|
||||
coerce/to-date)
|
||||
:else nil)
|
||||
|
||||
@@ -1,13 +1,9 @@
|
||||
(ns auto-ap.datomic.ledger
|
||||
(:require [datomic.api :as d]
|
||||
[auto-ap.graphql.utils :refer [->graphql limited-clients]]
|
||||
[auto-ap.utils :refer [dollars-0?]]
|
||||
[auto-ap.graphql.utils :refer [limited-clients]]
|
||||
[auto-ap.datomic :refer [merge-query apply-sort-3 apply-pagination add-sorter-fields conn]]
|
||||
[auto-ap.datomic :refer [uri]]
|
||||
|
||||
[clojure.tools.logging :as log]
|
||||
[clj-time.coerce :as c]
|
||||
[clj-time.core :as time]))
|
||||
[auto-ap.datomic.accounts :as d-accounts]))
|
||||
|
||||
(def export-read
|
||||
[:journal-entry/external-id
|
||||
@@ -34,12 +30,12 @@
|
||||
:account/name
|
||||
:account/numeric-code
|
||||
:account/location
|
||||
{:account/client-overrides [:account-client-override/name
|
||||
{:account-client-override/client [:db/id]}]}
|
||||
{:account/type [:db/ident :db/id]}
|
||||
{:bank-account/type [:db/ident :db/id]}]}]}])
|
||||
|
||||
(defn raw-graphql-ids [db args]
|
||||
(log/info "ARGS" args)
|
||||
|
||||
(let [query (cond-> {:query {:find []
|
||||
:in ['$ ]
|
||||
:where []}
|
||||
@@ -161,20 +157,27 @@
|
||||
|
||||
true
|
||||
(merge-query {:query {:find ['?sort-default '?e] :where ['[?e :journal-entry/date ?sort-default]]}}))]
|
||||
(->> (doto query log/info)
|
||||
|
||||
(->> query
|
||||
(d/query)
|
||||
(apply-sort-3 (update args :sort conj {:sort-key "default-2" :asc true}))
|
||||
(apply-pagination args))))
|
||||
|
||||
(defn graphql-results [ids db args]
|
||||
(defn graphql-results [ids db _]
|
||||
(let [results (->> (d/pull-many db '[* {:journal-entry/client [:client/name :client/code :db/id]
|
||||
:journal-entry/vendor [:vendor/name :db/id]
|
||||
:journal-entry/line-items [* {:journal-entry-line/account [*
|
||||
{:account/type [*]}
|
||||
{:account/client-overrides [:account-client-override/name
|
||||
{:account-client-override/client [:db/id]}]}
|
||||
{:bank-account/type [*]}]}]}]
|
||||
ids)
|
||||
(map #(update % :journal-entry/date c/from-date))
|
||||
(map (fn [je]
|
||||
(update je :journal-entry/line-items
|
||||
(fn [jels]
|
||||
(map
|
||||
#(update % :journal-entry-line/account d-accounts/clientize (:db/id (:journal-entry/client je)))
|
||||
jels)))))
|
||||
(filter (fn [je]
|
||||
(every?
|
||||
(fn [jel]
|
||||
@@ -191,12 +194,9 @@
|
||||
(defn get-graphql [args]
|
||||
(let [db (d/db conn)
|
||||
{ids-to-retrieve :ids matching-count :count} (raw-graphql-ids db args)]
|
||||
|
||||
[(->> (graphql-results ids-to-retrieve db args))
|
||||
matching-count]))
|
||||
|
||||
|
||||
|
||||
(defn filter-ids [ids]
|
||||
(if ids
|
||||
(->> {:query {:find ['?e]
|
||||
@@ -207,8 +207,3 @@
|
||||
(map first)
|
||||
vec)
|
||||
[]))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -142,6 +142,22 @@
|
||||
{:db/id accounts-payable
|
||||
:db/ident :account/accounts-payable}]]))
|
||||
|
||||
(defn add-account-search-terms [conn]
|
||||
[(->> (d/q '[:find ?i ?n
|
||||
:in $
|
||||
:where [?i :account/name ?n]]
|
||||
(d/db conn))
|
||||
(map (fn [[i n]]
|
||||
{:db/id i
|
||||
:account/search-terms n})))
|
||||
(->> (d/q '[:find ?i ?n
|
||||
:in $
|
||||
:where [?i :account-client-override/name ?n]]
|
||||
(d/db conn))
|
||||
(map (fn [[i n]]
|
||||
{:db/id i
|
||||
:account-client-override/search-terms n})))])
|
||||
|
||||
(defn migrate [conn]
|
||||
(let [
|
||||
norms-map (merge {:auto-ap/base-schema {:txes auto-ap.datomic/base-schema}
|
||||
@@ -491,7 +507,20 @@
|
||||
:db/valueType :db.type/boolean
|
||||
:db/cardinality :db.cardinality/one}]]}
|
||||
:auto-ap/add-payment-type-credit {:txes [[{:db/ident :payment-type/credit
|
||||
:db/doc "Credit for negative invoices"}]]}}
|
||||
:db/doc "Credit for negative invoices"}]]}
|
||||
:auto-ap/fulltext-accounts {:txes [[{:db/ident :account/search-terms
|
||||
:db/valueType :db.type/string
|
||||
:db/cardinality :db.cardinality/one
|
||||
:db/doc "a name search for accounts"
|
||||
:db/fulltext true}
|
||||
{:db/ident :account-client-override/search-terms
|
||||
:db/valueType :db.type/string
|
||||
:db/cardinality :db.cardinality/one
|
||||
:db/doc "a name search for accounts"
|
||||
:db/fulltext true}]]
|
||||
:requires [:auto-ap/add-account-overrides]}
|
||||
:auto-ap/add-search-terms-accounts {:txes-fn `add-account-search-terms
|
||||
:requires [:auto-ap/fulltext-accounts]}}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,14 @@
|
||||
(ns auto-ap.datomic.migrate.vendors
|
||||
(:require [datomic.api :as d]
|
||||
[auto-ap.datomic :refer [uri]]))
|
||||
(:require [datomic.api :as d]))
|
||||
|
||||
(defn add-vendor-search-terms [conn]
|
||||
[(->> (d/q '[:find ?i ?n
|
||||
:in $
|
||||
:where [?i :vendor/name ?n]]
|
||||
(d/db conn))
|
||||
(map (fn [[i n]]
|
||||
{:db/id i
|
||||
:vendor/search-terms n})))])
|
||||
|
||||
(def norms-map {:add-1099-stuff {:txes [[{:db/ident :vendor/legal-entity-first-name
|
||||
:db/doc "The first name for the legal entity"
|
||||
@@ -56,7 +64,15 @@
|
||||
:db/valueType :db.type/long
|
||||
:db/cardinality :db.cardinality/one
|
||||
:db/noHistory true}]
|
||||
]}})
|
||||
]}
|
||||
::make-fulltext-search {:txes [[{:db/ident :vendor/search-terms
|
||||
:db/valueType :db.type/string
|
||||
:db/cardinality :db.cardinality/many
|
||||
:db/doc "a name search for vendors"
|
||||
:db/fulltext true}]]
|
||||
:requires [:auto-ap/base-schema]}
|
||||
::add-vendor-search-terms {:txes-fn `add-vendor-search-terms
|
||||
:requires [::make-fulltext-search]}})
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -5,7 +5,8 @@
|
||||
[clj-time.coerce :as c]
|
||||
[clj-time.coerce :as coerce]
|
||||
[clojure.tools.logging :as log]
|
||||
[clojure.string :as str]))
|
||||
[clojure.string :as str]
|
||||
[auto-ap.datomic.accounts :as d-accounts]))
|
||||
|
||||
(defn sort-fn [sort-by]
|
||||
(cond
|
||||
@@ -194,11 +195,20 @@
|
||||
:transaction/accounts [:transaction-account/amount
|
||||
:db/id
|
||||
:transaction-account/location
|
||||
{:transaction-account/account [:db/id :account/name :account/numeric-code]}]
|
||||
{:transaction-account/account [:account/name :db/id
|
||||
:account/location
|
||||
{:account/client-overrides [:account-client-override/name
|
||||
{:account-client-override/client [:db/id]}]}]}]
|
||||
:transaction/yodlee-merchant [:db/id :yodlee-merchant/yodlee-id :yodlee-merchant/name]}]
|
||||
ids)
|
||||
(map #(update % :transaction/date c/from-date))
|
||||
(map #(update % :transaction/post-date c/from-date))
|
||||
(map #(update % :transaction/accounts
|
||||
(fn [tas]
|
||||
(map
|
||||
(fn [ta]
|
||||
(update ta :transaction-account/account d-accounts/clientize (:db/id (:transaction/client %))))
|
||||
tas))))
|
||||
(map (fn [transaction]
|
||||
(cond-> transaction
|
||||
(:transaction/payment transaction) (update-in [:transaction/payment :payment/date] c/from-date)
|
||||
@@ -240,7 +250,10 @@
|
||||
:transaction/accounts [:transaction-account/amount
|
||||
:db/id
|
||||
:transaction-account/location
|
||||
{ :transaction-account/account [:db/id :account/name :account/numeric-code]}]
|
||||
{ :transaction-account/account [:account/name :db/id
|
||||
:account/location
|
||||
{:account/client-overrides [:account-client-override/name
|
||||
{:account-client-override/client [:db/id]}]}]}]
|
||||
:transaction/yodlee-merchant [:db/id :yodlee-merchant/yodlee-id :yodlee-merchant/name]}]
|
||||
id)
|
||||
(update :transaction/date c/from-date)
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
(ns auto-ap.datomic.vendors
|
||||
(:require [datomic.api :as d]
|
||||
[auto-ap.graphql.utils :refer [limited-clients ]]
|
||||
(:require
|
||||
[auto-ap.datomic :refer [conn merge-query uri add-sorter-fields apply-pagination merge-query apply-sort-3]]
|
||||
[auto-ap.graphql.utils :refer [limited-clients]]
|
||||
[clojure.string :as str]
|
||||
[datomic.api :as d]
|
||||
[auto-ap.datomic.accounts :as d-accounts]))
|
||||
|
||||
[auto-ap.datomic :refer [uri conn merge-query]]))
|
||||
(defn <-datomic [a]
|
||||
(cond-> a
|
||||
(:vendor/legal-entity-tin-type a) (update :vendor/legal-entity-tin-type :db/ident)
|
||||
@@ -16,21 +19,28 @@
|
||||
nil)]
|
||||
(if clients
|
||||
(-> vendor
|
||||
(update :vendor/account-overrides (fn [ao] (filter #(clients (:db/id (:vendor-account-override/client %))) ao)))
|
||||
(update :vendor/account-overrides (fn [aos]
|
||||
(->> aos
|
||||
(filter #(clients (:db/id (:vendor-account-override/client %))))
|
||||
(map #(update % :vendor-account-override/account d-accounts/clientize (:db/id (:vendor-account-override/client %)))))))
|
||||
(update :vendor/terms-overrides (fn [to] (filter #(clients (:db/id (:vendor-terms-override/client %))) to)))
|
||||
(update :vendor/schedule-payment-dom (fn [to] (filter #(clients (:db/id (:vendor-schedule-payment-dom/client %))) to))))
|
||||
vendor)))
|
||||
(-> vendor
|
||||
(update :vendor/account-overrides (fn [aos]
|
||||
(->> aos
|
||||
(map #(update % :vendor-account-override/account d-accounts/clientize (:db/id (:vendor-account-override/client %)))))))))))
|
||||
|
||||
(def default-read
|
||||
'[* {:vendor/account-overrides [* {:vendor-account-override/client [:client/name :db/id]
|
||||
:vendor-account-override/account [:account/name :account/numeric-code :db/id]}]
|
||||
:vendor/terms-overrides [* {:vendor-terms-override/client [:client/name :client/code :db/id]}]
|
||||
:vendor/schedule-payment-dom [* {:vendor-schedule-payment-dom/client [:client/name :client/code :db/id]}]
|
||||
'[* {:vendor/account-overrides [* {:vendor-account-override/client [:client/name :db/id]
|
||||
:vendor-account-override/account [:account/name :account/numeric-code :db/id
|
||||
{:account/client-overrides [:account-client-override/client :account-client-override/name]}]}]
|
||||
:vendor/terms-overrides [* {:vendor-terms-override/client [:client/name :client/code :db/id]}]
|
||||
:vendor/schedule-payment-dom [* {:vendor-schedule-payment-dom/client [:client/name :client/code :db/id]}]
|
||||
:vendor/automatically-paid-when-due [:db/id :client/name]
|
||||
:vendor/legal-entity-tin-type [:db/ident :db/id]
|
||||
:vendor/legal-entity-1099-type [:db/ident :db/id]
|
||||
:vendor/default-account [:db/id :account/numeric-code :account/name]
|
||||
:vendor-usage/_vendor [:vendor-usage/client :vendor-usage/count]}])
|
||||
:vendor/legal-entity-tin-type [:db/ident :db/id]
|
||||
:vendor/legal-entity-1099-type [:db/ident :db/id]
|
||||
:vendor/default-account [:db/id :account/numeric-code :account/name]
|
||||
:vendor-usage/_vendor [:vendor-usage/client :vendor-usage/count]}])
|
||||
|
||||
(defn get-usages [args]
|
||||
(->> (cond-> {:query {:find ['?v '?c '(count ?e)]
|
||||
@@ -58,6 +68,30 @@
|
||||
(update usages v (fnil conj []) {:client-id c :count cnt}))
|
||||
{})))
|
||||
|
||||
(defn raw-graphql-ids [db args]
|
||||
(let [query (cond-> {:query {:find []
|
||||
:in ['$]
|
||||
:where []}
|
||||
:args [db]}
|
||||
(:sort args) (add-sorter-fields {"name" ['[?e :vendor/name ?sort-name]]}
|
||||
args)
|
||||
|
||||
(not (str/blank? (:name-like args)))
|
||||
(merge-query {:query {:in ['?name-like]
|
||||
:where ['[?e :vendor/name ?n]
|
||||
'[(re-find ?name-like ?n)]]}
|
||||
:args [(re-pattern (str "(?i)" (:name-like args)))]})
|
||||
|
||||
true
|
||||
(merge-query {:query {:find ['?e]
|
||||
:where ['[?e :vendor/name]]}}))]
|
||||
|
||||
|
||||
(cond->> query
|
||||
true (d/query)
|
||||
true (apply-sort-3 args)
|
||||
true (apply-pagination args))))
|
||||
|
||||
(defn trim-usage [v limited-clients]
|
||||
(->> (if limited-clients
|
||||
(update v :usage (fn [usages]
|
||||
@@ -73,22 +107,40 @@
|
||||
|
||||
))
|
||||
|
||||
(defn graphql-results [ids db args]
|
||||
(let [results (->> (d/pull-many db default-read ids)
|
||||
(group-by :db/id))
|
||||
vendors (->> ids
|
||||
(map results)
|
||||
(map first)
|
||||
(map #(cleanse (:id args) %))
|
||||
(map <-datomic))]
|
||||
vendors))
|
||||
|
||||
(defn get-graphql [args]
|
||||
(let [db (d/db conn)
|
||||
{ids-to-retrieve :ids matching-count :count} (raw-graphql-ids db args)]
|
||||
[(->> (graphql-results ids-to-retrieve db args))
|
||||
matching-count])
|
||||
|
||||
)
|
||||
|
||||
(defn get-graphql-by-id [args id]
|
||||
(->> (cond-> {:query {:find [(list 'pull '?e default-read)]
|
||||
:in ['$]
|
||||
:in ['$ '?e]
|
||||
:where ['[?e :vendor/name]]}
|
||||
:args [(d/db (d/connect uri))]})
|
||||
:args [(d/db (d/connect uri)) id]})
|
||||
(d/query)
|
||||
(map first)
|
||||
(map #(cleanse (:id args) %))
|
||||
(map <-datomic)
|
||||
(map #(trim-usage % (limited-clients (:id args))))
|
||||
#_(map #(assoc % :usage (get usages (:db/id %))))))
|
||||
first))
|
||||
|
||||
(defn get-by-id [id]
|
||||
|
||||
(->> (d/q '[:find (pull ?e [*
|
||||
{:default-account [:account/name :db/id :account/location]
|
||||
{:vendor/default-account [:account/name :db/id :account/location]
|
||||
:vendor/legal-entity-tin-type [:db/ident :db/id]
|
||||
:vendor/legal-entity-1099-type [:db/ident :db/id]
|
||||
:vendor/account-overrides [* {:vendor-account-override/client [:client/name :db/id]
|
||||
|
||||
@@ -98,6 +98,15 @@
|
||||
:message
|
||||
{:fields {:message {:type 'String}}}
|
||||
|
||||
:search_result
|
||||
{:fields {:name {:type 'String}
|
||||
:id {:type :id}}}
|
||||
|
||||
:account_search_result
|
||||
{:fields {:name {:type 'String}
|
||||
:id {:type :id}
|
||||
:location {:type 'String}}}
|
||||
|
||||
:yodlee_provider_account
|
||||
{:fields {:id {:type 'Int}
|
||||
:client {:type :client}
|
||||
@@ -290,11 +299,23 @@
|
||||
:sales_order_total {:type :money}
|
||||
:sales_order_tax {:type :money}}}
|
||||
|
||||
:vendor_page {:fields {:vendors {:type '(list :vendor)}
|
||||
:count {:type 'Int}
|
||||
:total {:type 'Int}
|
||||
:start {:type 'Int}
|
||||
:end {:type 'Int}}}
|
||||
|
||||
:account_page {:fields {:accounts {:type '(list :account)}
|
||||
:count {:type 'Int}
|
||||
:total {:type 'Int}
|
||||
:start {:type 'Int}
|
||||
:end {:type 'Int}}}
|
||||
|
||||
:reminder_page {:fields {:reminders {:type '(list :reminder)}
|
||||
:count {:type 'Int}
|
||||
:total {:type 'Int}
|
||||
:start {:type 'Int}
|
||||
:end {:type 'Int}}}
|
||||
:count {:type 'Int}
|
||||
:total {:type 'Int}
|
||||
:start {:type 'Int}
|
||||
:end {:type 'Int}}}
|
||||
:check_result {:fields {:invoices {:type '(list :invoice)}
|
||||
:pdf_url {:type 'String}}}
|
||||
|
||||
@@ -343,9 +364,21 @@
|
||||
:args {:client_id {:type :id}}
|
||||
:resolve :get-yodlee-provider-account-page}
|
||||
|
||||
:accounts {:type '(list :account)
|
||||
:args {:account_set {:type 'String}}
|
||||
:resolve :get-accounts}
|
||||
:account_page {:type :account_page
|
||||
:args {:name_like {:type 'String}
|
||||
:numeric_code {:type 'Int}
|
||||
:start {:type 'Int}
|
||||
:per_page {:type 'Int}
|
||||
:sort {:type '(list :sort_item)}}
|
||||
:resolve :get-accounts}
|
||||
|
||||
:search_vendor {:type '(list :search_result)
|
||||
:args {:query {:type 'String}}
|
||||
:resolve :search-vendor}
|
||||
:search_account {:type '(list :account_search_result)
|
||||
:args {:query {:type 'String}
|
||||
:client_id {:type :id}}
|
||||
:resolve :search-account}
|
||||
|
||||
|
||||
|
||||
@@ -386,14 +419,21 @@
|
||||
:per_page {:type 'Int}
|
||||
:sort {:type '(list :sort_item)}}
|
||||
:resolve :get-sales-order-page}
|
||||
|
||||
|
||||
|
||||
|
||||
:vendor {:type '(list :vendor)
|
||||
:vendor {:type :vendor_page
|
||||
:args {:name_like {:type 'String}
|
||||
:start {:type 'Int}
|
||||
:per_page {:type 'Int}
|
||||
:sort {:type '(list :sort_item)}}
|
||||
:resolve :get-vendor}
|
||||
:user {:type '(list :user)
|
||||
:resolve :get-user}}
|
||||
:user {:type '(list :user)
|
||||
:resolve :get-user}
|
||||
:vendor_by_id {:type :vendor
|
||||
:args {:id {:type :id}}
|
||||
:resolve :vendor-by-id}
|
||||
:account_for_vendor {:type :account
|
||||
:args {:client_id {:type :id}
|
||||
:vendor_id {:type :id}}
|
||||
:resolve :account-for-vendor}}
|
||||
|
||||
:input-objects
|
||||
{
|
||||
@@ -693,7 +733,7 @@
|
||||
'[(get-else $ ?je :journal-entry-line/debit 0.0) ?debit]
|
||||
'[(get-else $ ?je :journal-entry-line/credit 0.0) ?credit]]}
|
||||
:args [(d/db (d/connect uri)) client_id]}))
|
||||
bills-due-soon (d/query {:query {:find '[?due ?outstanding ?invoice-number ?vendor-id]
|
||||
bills-due-soon (d/query {:query {:find '[?due ?outstanding ?invoice-number ?vendor-id ?vendor-name]
|
||||
:in '[$ ?client ?due-before]
|
||||
:where ['[?i :invoice/client ?client]
|
||||
'[?i :invoice/status :invoice-status/unpaid]
|
||||
@@ -701,7 +741,8 @@
|
||||
'[(<= ?due ?due-before)]
|
||||
'[?i :invoice/outstanding-balance ?outstanding]
|
||||
'[?i :invoice/invoice-number ?invoice-number]
|
||||
'[?i :invoice/vendor ?vendor-id]]}
|
||||
'[?i :invoice/vendor ?vendor-id]
|
||||
'[?vendor-id :vendor/name ?vendor-name]]}
|
||||
:args [(d/db (d/connect uri)) client_id (coerce/to-date (t/plus (time/local-now) (t/days 180)))]})
|
||||
outstanding-checks (reduce
|
||||
+
|
||||
@@ -739,10 +780,10 @@
|
||||
|
||||
{:beginning_balance total-cash
|
||||
:outstanding_payments outstanding-checks
|
||||
:invoices_due_soon (mapv (fn [[due outstanding invoice-number vendor-id]]
|
||||
:invoices_due_soon (mapv (fn [[due outstanding invoice-number vendor-id vendor-name]]
|
||||
{:due (coerce/to-date-time due)
|
||||
:invoice_number invoice-number
|
||||
:vendor {:id vendor-id}
|
||||
:vendor {:id vendor-id :name vendor-name}
|
||||
:outstanding_balance outstanding})
|
||||
bills-due-soon)
|
||||
:upcoming_credits (into (mapv
|
||||
@@ -768,7 +809,7 @@
|
||||
(attach-resolvers {
|
||||
:get-yodlee-provider-account-page gq-yodlee2/get-yodlee-provider-account-page
|
||||
:get-all-sales-orders get-all-sales-orders
|
||||
:get-accounts gq-accounts/get-accounts
|
||||
:get-accounts gq-accounts/get-graphql
|
||||
:get-sales-order-page gq-sales-orders/get-sales-orders-page
|
||||
:get-transaction-rule-page gq-transaction-rules/get-transaction-rule-page
|
||||
:get-transaction-rule-matches gq-transaction-rules/get-transaction-rule-matches
|
||||
@@ -777,6 +818,8 @@
|
||||
:get-cash-flow get-cash-flow
|
||||
:get-yodlee-merchants ym/get-yodlee-merchants
|
||||
:get-intuit-bank-accounts gq-intuit-bank-accounts/get-intuit-bank-accounts
|
||||
:vendor-by-id gq-vendors/get-by-id
|
||||
:account-for-vendor gq-accounts/default-for-vendor
|
||||
:get-user get-user
|
||||
:mutation/delete-transaction-rule gq-transaction-rules/delete-transaction-rule
|
||||
:mutation/edit-user gq-users/edit-user
|
||||
@@ -787,7 +830,9 @@
|
||||
:mutation/upsert-account gq-accounts/upsert-account
|
||||
:mutation/merge-vendors gq-vendors/merge-vendors
|
||||
:mutation/request-import gq-requests/request-import
|
||||
:get-vendor gq-vendors/get-graphql})
|
||||
:get-vendor gq-vendors/get-graphql
|
||||
:search-vendor gq-vendors/search
|
||||
:search-account gq-accounts/search})
|
||||
gq-checks/attach
|
||||
gq-ledger/attach
|
||||
gq-reports/attach
|
||||
|
||||
@@ -1,39 +1,53 @@
|
||||
(ns auto-ap.graphql.accounts
|
||||
(:require [datomic.api :as d]
|
||||
[auto-ap.datomic.accounts :as d-accounts]
|
||||
[auto-ap.graphql.utils :refer [->graphql <-graphql enum->keyword] ]
|
||||
[auto-ap.datomic :refer [uri merge-query remove-nils audit-transact]]
|
||||
[clojure.tools.logging :as log]))
|
||||
(:require
|
||||
[auto-ap.datomic :refer [audit-transact conn remove-nils]]
|
||||
[auto-ap.datomic.accounts :as d-accounts]
|
||||
[auto-ap.graphql.utils
|
||||
:refer [->graphql
|
||||
<-graphql
|
||||
assert-admin
|
||||
assert-can-see-client
|
||||
enum->keyword
|
||||
result->page]]
|
||||
[datomic.api :as d]))
|
||||
|
||||
(defn get-graphql [context args _]
|
||||
(assert-admin (:id context))
|
||||
(let [args (assoc args :id (:id context))
|
||||
[accounts accounts-count ] (d-accounts/get-graphql (<-graphql args))]
|
||||
(result->page accounts accounts-count :accounts args)))
|
||||
|
||||
(defn default-for-vendor [context args _]
|
||||
(assert-can-see-client (:id context) (:client_id args))
|
||||
(let [result (d-accounts/get-for-vendor (:vendor_id args) (:client_id args))]
|
||||
(->graphql (d-accounts/clientize result (:client_id args)))))
|
||||
|
||||
(defn get-accounts [context args value]
|
||||
(->graphql (d-accounts/get-accounts (<-graphql args))))
|
||||
|
||||
(defn upsert-account [context args value]
|
||||
(defn upsert-account [context args _]
|
||||
(let [{{:keys [id client-overrides numeric-code location applicability account-set name type]} :account} (<-graphql args)]
|
||||
(when-not id
|
||||
(when (seq (d/query {:query {:find ['?e]
|
||||
:in '[$ ?account-set ?numeric-code]
|
||||
:where ['[?e :account/account-set ?account-set]
|
||||
'[?e :account/numeric-code ?numeric-code]]}
|
||||
:args [(d/db (d/connect uri)) account-set numeric-code]}))
|
||||
:args [(d/db conn) account-set numeric-code]}))
|
||||
|
||||
(throw (ex-info (str "Account set " account-set " already has an account for code " numeric-code)
|
||||
{} ))))
|
||||
|
||||
(let [original (if id (d/entity (d/db (d/connect uri)) id))
|
||||
(let [original (when id
|
||||
(d/entity (d/db conn) id))
|
||||
result (audit-transact (cond->
|
||||
[(remove-nils
|
||||
{:db/id (or id "new-account")
|
||||
:account/name name
|
||||
:account/search-terms name
|
||||
:account/type (keyword "account-type" (clojure.core/name type))
|
||||
:account/applicability (enum->keyword applicability "account-applicability")
|
||||
:account/account-set account-set
|
||||
:account/location location
|
||||
:account/numeric-code (if-not id
|
||||
:account/numeric-code (when-not id
|
||||
numeric-code)
|
||||
:account/code (if-not id
|
||||
:account/code (when-not id
|
||||
(str numeric-code))})
|
||||
[:reset (or id "new-account") :account/client-overrides
|
||||
(mapv
|
||||
@@ -41,10 +55,55 @@
|
||||
(remove-nils
|
||||
{:db/id (:id client-override)
|
||||
:account-client-override/client (:client-id client-override)
|
||||
:account-client-override/name (:name client-override)}))
|
||||
:account-client-override/name (:name client-override)
|
||||
:account-client-override/search-terms (:name client-override)}))
|
||||
client-overrides)]]
|
||||
(and (not location) (:account/location original)) (conj [:db/retract (or id "new-account") :account/location (:account/location original)]))
|
||||
(:id context))]
|
||||
(->graphql
|
||||
(d-accounts/get-by-id (or id (get-in result [:tempids "new-account"])))))))
|
||||
|
||||
(defn search [context {query :query client :client_id} _]
|
||||
(when client
|
||||
(assert-can-see-client (:id context) client))
|
||||
(let [num (some-> (re-find #"([0-9]+)" query)
|
||||
second
|
||||
(not-empty )
|
||||
Integer/parseInt)]
|
||||
(if num
|
||||
(->> (d/q '[:find ?n (pull ?i [:db/id :account/numeric-code :account/location])
|
||||
:in $ ?numeric-code
|
||||
:where [?i :account/numeric-code ?numeric-code]
|
||||
[?i :account/name ?n]]
|
||||
(d/db conn)
|
||||
num)
|
||||
(map (fn [[n a]]
|
||||
{:name (str (:account/numeric-code a) " - " n)
|
||||
:id (:db/id a)
|
||||
:location (:account/location a)})))
|
||||
|
||||
(->> (d/q '[:find ?n (pull ?i [:db/id :account/numeric-code :account/location]) ?s
|
||||
:in $ ?q
|
||||
:where [(fulltext $ :account/search-terms ?q) [[?i ?n _ ?s]]]
|
||||
[?i :account/numeric-code ?numeric-code]
|
||||
(or [?i :account/applicability :account-applicability/global]
|
||||
[?i :account/applicability :account-applicability/optional])]
|
||||
(d/db conn)
|
||||
query)
|
||||
(concat (when client
|
||||
(d/q '[:find ?n (pull ?a [:db/id :account/numeric-code :account/location]) ?s
|
||||
:in $ ?c ?q
|
||||
:where
|
||||
[?i :account-client-override/client ?c]
|
||||
[(fulltext $ :account-client-override/search-terms ?q) [[?i ?n _ ?s]]]
|
||||
[?a :account/client-overrides ?i]
|
||||
[?a :account/numeric-code ?numeric-code]]
|
||||
(d/db conn)
|
||||
client
|
||||
query)))
|
||||
(sort-by (comp - last))
|
||||
(map (fn [[n a]]
|
||||
{:name (str (:account/numeric-code a) " - " n)
|
||||
:id (:db/id a)
|
||||
:location (:account/location a)}))))))
|
||||
|
||||
|
||||
@@ -366,7 +366,12 @@
|
||||
(let [type (keyword "payment-type" (name type))
|
||||
invoices (d-invoices/get-multi (map :invoice-id invoice-payments))
|
||||
client (d-clients/get-by-id client-id)
|
||||
vendors (by :db/id (d-vendors/get-graphql {}))
|
||||
vendors (->> (d/q '[:find [?e ...]
|
||||
:in $
|
||||
:where [?e :vendor/name]]
|
||||
(d/db conn))
|
||||
(d/pull-many (d/db conn) d-vendors/default-read)
|
||||
(by :db/id))
|
||||
invoice-amounts (by :invoice-id :amount invoice-payments)
|
||||
invoices-grouped-by-vendor (group-by (comp :db/id :invoice/vendor) invoices)
|
||||
bank-account (d-bank-accounts/get-by-id bank-account-id)
|
||||
|
||||
@@ -307,6 +307,7 @@
|
||||
(assert (:invoice/client invoice))
|
||||
(assert-can-see-client (:id context) (:db/id (:invoice/client invoice)))
|
||||
(assert-not-locked (:db/id (:invoice/client invoice)) (:invoice/date invoice))
|
||||
(assert (not (seq (:invoice-payment/_invoice invoice))))
|
||||
(audit-transact [[:db/add id :invoice/status :invoice-status/unpaid]
|
||||
[:db/add id :invoice/outstanding-balance (:invoice/total invoice)]
|
||||
[:db/retract id :invoice/scheduled-payment (:invoice/scheduled-payment invoice)]]
|
||||
|
||||
@@ -134,13 +134,18 @@
|
||||
|
||||
(defn bulk-code-transactions [context args _]
|
||||
(assert-admin (:id context))
|
||||
(when-not (:client_id args)
|
||||
(throw (ex-info "Client is required"
|
||||
{:validation-error "client is required"})))
|
||||
(let [args (assoc args :id (:id context))
|
||||
locations (:client/locations (d/pull (d/db conn)
|
||||
[:client/locations]
|
||||
(:client_id (:filters args))))
|
||||
(:client_id args)))
|
||||
all-ids (all-ids-not-locked (get-ids-matching-filters args))
|
||||
transactions (d/pull-many (d/db conn) '[:db/id :transaction/amount] (vec all-ids))
|
||||
account-total (reduce + 0 (map (fn [x] (:percentage x)) (:accounts args)))]
|
||||
(log/info "client is" locations)
|
||||
|
||||
(when
|
||||
(and
|
||||
(seq (:accounts args))
|
||||
@@ -149,14 +154,13 @@
|
||||
(throw (ex-info error {:validation-error error}))))
|
||||
|
||||
(doseq [a (:accounts args)
|
||||
:let [{:keys [:account/location :account/name]} (d/entity (d/db conn) (:account_id a))
|
||||
client (d/entity (d/db conn) (:client_id (:filters args)))]]
|
||||
:let [{:keys [:account/location :account/name]} (d/entity (d/db conn) (:account_id a))]]
|
||||
(when (and location (not= location (:location a)))
|
||||
(let [err (str "Account " name " uses location " (:location a) ", but is supposed to be " location)]
|
||||
(throw (ex-info err {:validation-error err}) )))
|
||||
|
||||
(when (and (not location)
|
||||
(not (get (into #{"Shared"} (:client/locations client))
|
||||
(not (get (into #{"Shared"} locations)
|
||||
(:location a))))
|
||||
(let [err (str "Account " name " uses location " (:location a) ", but doesn't belong to the client.")]
|
||||
(throw (ex-info err {:validation-error err}) ))))
|
||||
@@ -599,6 +603,7 @@
|
||||
:resolve :mutation/bulk-change-transaction-status}
|
||||
:bulk_code_transactions {:type :message
|
||||
:args {:filters {:type :transaction_filters}
|
||||
:client_id {:type :id}
|
||||
:vendor {:type :id}
|
||||
:approval_status {:type :transaction_approval_status}
|
||||
:accounts {:type '(list :edit_percentage_account)}
|
||||
|
||||
@@ -1,23 +1,43 @@
|
||||
(ns auto-ap.graphql.vendors
|
||||
(:require [auto-ap.graphql.utils :refer [->graphql assert-can-see-client assert-admin is-admin? enum->keyword]]
|
||||
[auto-ap.datomic.vendors :as d-vendors]
|
||||
[auto-ap.time :refer [parse iso-date]]
|
||||
[datomic.api :as d]
|
||||
[auto-ap.datomic :refer [uri remove-nils audit-transact conn]]
|
||||
[clj-time.coerce :as coerce]
|
||||
[clojure.set :as set]
|
||||
[clojure.tools.logging :as log]))
|
||||
(:require
|
||||
[auto-ap.datomic :refer [audit-transact conn remove-nils]]
|
||||
[auto-ap.datomic.vendors :as d-vendors]
|
||||
[auto-ap.graphql.utils
|
||||
:refer [->graphql
|
||||
<-graphql
|
||||
assert-admin
|
||||
assert-failure
|
||||
enum->keyword
|
||||
is-admin?
|
||||
result->page]]
|
||||
[clojure.set :as set]
|
||||
[clojure.tools.logging :as log]
|
||||
[datomic.api :as d]))
|
||||
|
||||
(defn can-user-edit-vendor? [vendor-id id]
|
||||
(if (is-admin? id)
|
||||
true
|
||||
(empty?
|
||||
(set/difference (set (d/q '[:find [?c ...]
|
||||
:in $ ?v
|
||||
:where [?vu :vendor-usage/vendor ?v]
|
||||
[?vu :vendor-usage/client ?c]
|
||||
[?vu :vendor-usage/count ?d]
|
||||
[(>= ?d 0)]]
|
||||
(d/db conn)
|
||||
vendor-id))
|
||||
(set (map :db/id (:user/clients id)))))))
|
||||
|
||||
(defn upsert-vendor [context {{:keys [id name hidden terms code print_as primary_contact secondary_contact address default_account_id invoice_reminder_schedule schedule_payment_dom terms_overrides account_overrides] :as in} :vendor} value]
|
||||
(when id
|
||||
(assert-admin (:id context)))
|
||||
#_(Thread/sleep 3000)
|
||||
#_(throw (ex-info "" {:validation-error "can't do that."}))
|
||||
(let [hidden (if (is-admin? (:id context))
|
||||
|
||||
(when (and id (not (can-user-edit-vendor? id (:id context))))
|
||||
(assert-failure "This vendor is managed by Integreat. Please reach out to ben@integreatconsult.com for your changes."))
|
||||
(let [
|
||||
hidden (if (is-admin? (:id context))
|
||||
hidden
|
||||
false)
|
||||
|
||||
existing (when id
|
||||
(d/pull (d/db conn) '[:vendor/name] id))
|
||||
terms-overrides (mapv
|
||||
(fn [to]
|
||||
(cond->
|
||||
@@ -90,7 +110,8 @@
|
||||
(mapv
|
||||
(fn [apwd]
|
||||
{:db/id apwd})
|
||||
(:automatically_paid_when_due in))]))
|
||||
(:automatically_paid_when_due in))])
|
||||
(not= (:vendor/name existing) name) (conj [:reset (if id id "vendor") :vendor/search-terms [name]]))
|
||||
|
||||
_ (log/info "Upserting vendor" transaction)
|
||||
transaction-result (audit-transact transaction (:id context))]
|
||||
@@ -114,6 +135,34 @@
|
||||
(audit-transact transaction (:id context))
|
||||
to))
|
||||
|
||||
(defn get-graphql [context args value]
|
||||
|
||||
(defn get-graphql [context args _]
|
||||
(assert-admin (:id context))
|
||||
(let [args (assoc args :id (:id context))
|
||||
[vendors vendors-count ] (d-vendors/get-graphql (<-graphql args))]
|
||||
(result->page vendors vendors-count :vendors args)))
|
||||
|
||||
(defn get-by-id [context args _]
|
||||
(->graphql
|
||||
(d-vendors/get-graphql (assoc args :id (:id context)))))
|
||||
(d-vendors/get-graphql-by-id (assoc args :id (:id context))
|
||||
(:id args))))
|
||||
|
||||
(defn search [context args _]
|
||||
(let [data (if (is-admin? (:id context))
|
||||
(d/q '[:find ?n ?i ?s
|
||||
:in $ ?q
|
||||
:where [(fulltext $ :vendor/search-terms ?q) [[?i ?n _ ?s]]]]
|
||||
(d/db conn)
|
||||
(:query args))
|
||||
(d/q '[:find ?n ?i ?s
|
||||
:in $ ?q
|
||||
:where [(fulltext $ :vendor/search-terms ?q) [[?i ?n _ ?s]]]
|
||||
(not [?i :vendor/hidden true])]
|
||||
(d/db conn)
|
||||
(:query args)))]
|
||||
|
||||
(->> data
|
||||
(sort-by last)
|
||||
(map (fn [[n i]]
|
||||
{:name n
|
||||
:id i})))))
|
||||
|
||||
Reference in New Issue
Block a user