implemented crud

This commit is contained in:
Bryce Covert
2019-05-07 18:18:57 -07:00
parent a1abb4b05e
commit 8c50085fcc
11 changed files with 355 additions and 22 deletions

View File

@@ -12,7 +12,7 @@
[clj-time.core :as time]
[clj-time.coerce :as coerce]))
(def uri "datomic:sql://invoices-backup?jdbc:postgresql://database:5432/datomic?user=datomic&password=datomic")
(def uri "datomic:sql://invoices?jdbc:postgresql://database:5432/datomic?user=datomic&password=datomic")
(defn create-database []
(d/create-database uri))

View File

@@ -20,12 +20,15 @@
:args [db]}
(:sort-by args) (add-sorter-field {"client" ['[?e :transaction-rule/client ?c]
'[?c :client/name ?sorter]]
"yodlee-merchant" ['[?e :transaction-rule/yodlee-merchant ?c]
'[?c :yodlee-merchant/name ?sorter]]
"bank-account" ['[?e :transaction-rule/bank-account ?c]
'[?c :bank-account/name ?sorter]]
"amount_lte" ['[?e :transaction-rule/amount-lte ?sorter]]
"amount_gte" ['[?e :transaction-rule/amount-gte ?sorter]]
"description" ['[?e :transaction-rule/description ?sorter]]
"note" ['[?e :transaction-rule/note ?sorter]]
"amount-lte" ['[?e :transaction-rule/amount-lte ?sorter]]
"amount-gte" ['[?e :transaction-rule/amount-gte ?sorter]]
}
args)

View File

@@ -39,7 +39,14 @@
:ident {:parse (schema/as-conformer (fn [x] {:db/ident x}))
:serialize (schema/as-conformer #(or (:ident %) (:db/ident %) %))}
:iso_date {:parse (schema/as-conformer #(time/parse % time/iso-date))
:serialize (schema/as-conformer #(time/unparse % time/iso-date))}}
:serialize (schema/as-conformer #(time/unparse % time/iso-date))}
:money {:parse (schema/as-conformer #(if (string? %)
(Double/parseDouble %)
%))
:serialize (schema/as-conformer #(if (double? %)
(str %)
%))
}}
:objects
{
:client
@@ -493,6 +500,15 @@
:vendor_id {:type :id}
:accounts {:type '(list :edit_expense_account)}}}
:edit_transaction_rule
{:fields {:id {:type :id}
:description {:type 'String}
:note {:type 'String}
:bank_account_id {:type :id}
:client_id {:type :id}
:amount_lte {:type :money}
:amount_gte {:type :money}}}
:edit_account
{:fields {:id {:type :id}
:type {:type :account_type}
@@ -552,6 +568,10 @@
:upsert_vendor {:type :vendor
:args {:vendor {:type :add_vendor}}
:resolve :mutation/upsert-vendor}
:upsert_transaction_rule {:type :transaction_rule
:args {:transaction_rule {:type :edit_transaction_rule}}
:resolve :mutation/upsert-transaction-rule}
:add_invoice {:type :invoice
:args {:invoice {:type :add_invoice}}
:resolve :mutation/add-invoice}
@@ -739,6 +759,7 @@
:mutation/add-and-print-invoice gq-invoices/add-and-print-invoice
:mutation/edit-invoice gq-invoices/edit-invoice
:mutation/edit-transaction gq-transactions/edit-transaction
:mutation/upsert-transaction-rule gq-transaction-rules/upsert-transaction-rule
:mutation/match-transaction gq-transactions/match-transaction
:mutation/edit-client gq-clients/edit-client
:mutation/upsert-vendor gq-vendors/upsert-vendor

View File

@@ -1,8 +1,28 @@
(ns auto-ap.graphql.transaction-rules
(:require [auto-ap.datomic.transaction-rules :as tr]
[datomic.api :as d]
[auto-ap.datomic :refer [remove-nils uri]]
[auto-ap.graphql.utils :refer [->graphql <-graphql limited-clients assert-admin result->page]]))
(defn get-transaction-rule-page [context args value]
(let [args (assoc args :id (:id context))
[journal-entries journal-entries-count] (tr/get-graphql (<-graphql args))]
(result->page journal-entries journal-entries-count :transaction_rules args)))
(defn upsert-transaction-rule [context {{:keys [id description note client_id bank_account_id amount_lte amount_gte ]} :transaction_rule :as z} value]
(let [transaction [(remove-nils #:transaction-rule {:db/id (if id
id
"transaction-rule")
:description description
:note note
:client client_id
:bank-account bank_account_id
:amount-lte amount_lte
:amount-gte amount_gte})]
_ (println transaction)
transaction-result @(d/transact (d/connect uri) transaction)]
(println "HI" (or (-> transaction-result )
id))
(-> (tr/get-by-id (or (-> transaction-result :tempids (get "transaction-rule"))
id))
(->graphql))))

View File

@@ -0,0 +1,11 @@
(ns auto-ap.entities.transaction-rule
(:require [clojure.spec.alpha :as s]))
(s/def ::client (s/nilable map?))
(s/def ::description (s/nilable string?))
(s/def ::amount-gte (s/nilable double?))
(s/def ::amount-lte (s/nilable double?))
(s/def ::note (s/nilable string?))
(s/def ::bank-account (s/nilable map?))
(s/def ::transaction-rule (s/keys :req-un [::client ::description ::amount-gte ::amount-lte ::note ::bank-account]))

View File

@@ -63,6 +63,11 @@
(fn [client]
(->> client :bank-accounts (filter #(= (:type %) :check)) (sort-by :sort-order))))
(re-frame/reg-sub
::real-bank-accounts-for-client
(fn [db [_ {:keys [id]}]]
(sort-by :sort-order (-> db :clients (get id) :bank-accounts ))))
(re-frame/reg-sub
::locations-for-client

View File

@@ -4,9 +4,14 @@
[auto-ap.views.components.admin.side-bar :refer [admin-side-bar]]
[auto-ap.views.components.layouts :refer [appearing-side-bar side-bar-layout]]
[auto-ap.views.pages.admin.rules.table :as table]
[auto-ap.views.pages.admin.rules.form :as form]
[auto-ap.views.pages.admin.rules.common :refer [default-read]]
[auto-ap.views.utils :refer [dispatch-event with-user]]
[auto-ap.utils :refer [replace-by]]
[re-frame.core :as re-frame]))
;; SUBS
(re-frame/reg-sub
::notification
(fn [db]
@@ -22,13 +27,22 @@
(fn [db]
(-> db (::params {}))))
(def rule-read [:description-matches])
(re-frame/reg-event-db
::edit-completed
(fn [db [_ edit-transaction-rule]]
(println edit-transaction-rule)
(-> db
(update-in [::page :transaction-rules]
replace-by :id (assoc edit-transaction-rule :class "live-added")))))
;; EVENTS
(re-frame/reg-event-db
::received
(fn [db [_ data]]
(println data)
(-> db
(update ::page merge (first (:rule-page data)))
(update ::page merge (:transaction-rule-page data))
(assoc-in [:status :loading] false))))
(re-frame/reg-event-fx
@@ -39,14 +53,22 @@
(assoc-in [:status :loading] true)
(assoc-in [::params] params))
:graphql {:token user
:query-obj {:venia/queries [[:rule_page
:query-obj {:venia/queries [[:transaction_rule_page
(assoc params :client-id (:id @(re-frame/subscribe [::subs/client])))
[[:rules rule-read]
[[:transaction-rules default-read]
:total
:start
:end]]]}
:on-success [::received]}}))
(re-frame/reg-event-fx
::new-rule-clicked
(fn [{:keys [db]} _]
{:dispatch [::form/adding {:client @(re-frame/subscribe [::subs/client])}]}))
;; VIEWS
(def rules-content
(with-meta
(fn []
@@ -57,17 +79,19 @@
[:h1.title "Transaction Rules"]
(when (= "admin" (:user/role user))
[:div.is-pulled-right
[:button.button.is-outlined.is-primary {:on-click (dispatch-event [::create-rule-clicked])} "New Rule"]])
[:button.button.is-outlined.is-primary {:on-click (dispatch-event [::new-rule-clicked])} "New Rule"]])
[table/table {:id :transactions
:params (re-frame/subscribe [::params])
:rule-page (re-frame/subscribe [::page])
:status (re-frame/subscribe [::subs/status])
:on-params-change (fn [params]
(re-frame/dispatch [::params-change params]))}]
]))
{:component-will-mount #(re-frame/dispatch-sync [::params-change {}]) }))
(defn admin-rules-page []
(let [{:keys [active?]} @(re-frame/subscribe [::forms/form ::new-client])]
(let [{:keys [active?]} @(re-frame/subscribe [::forms/form ::form/form])]
[side-bar-layout {:side-bar [admin-side-bar {}]
:main [rules-content]
:right-side-bar [appearing-side-bar {:visible? active?} [:div]] }]))
:right-side-bar [appearing-side-bar {:visible? active?}
[form/form {:rule-saved [::edit-completed]}]] }]))

View File

@@ -0,0 +1,10 @@
(ns auto-ap.views.pages.admin.rules.common)
(def default-read [:id
:description
:note
:amount-gte
:amount-lte
[:client [:name :id]]
[:bank-account [:name :id]]
])

View File

@@ -0,0 +1,149 @@
(ns auto-ap.views.pages.admin.rules.form
(:require [auto-ap.entities.transaction-rule :as entity]
[auto-ap.events :as events]
[auto-ap.forms :as forms]
[auto-ap.subs :as subs]
[auto-ap.utils :refer [dollars=]]
[auto-ap.views.components.dropdown :refer [drop-down]]
[auto-ap.views.components.expense-accounts-field :as expense-accounts-field :refer [expense-accounts-field recalculate-amounts]]
[auto-ap.views.components.layouts :as layouts]
[auto-ap.views.components.typeahead :refer [typeahead-entity]]
[auto-ap.views.pages.admin.rules.common :refer [default-read]]
[auto-ap.views.utils :refer [date->str date-picker dispatch-event standard with-user]]
[cljs-time.core :as c]
[clojure.spec.alpha :as s]
[clojure.string :as str]
[re-frame.core :as re-frame]))
;; SUBS
(re-frame/reg-sub
::can-submit
:<- [::forms/form ::form]
(fn [{:keys [data status]} _]
(s/valid? ::entity/transaction-rule data)))
(re-frame/reg-sub
::query
:<- [::forms/form ::form]
(fn [{:keys [data] }]
{:venia/operation {:operation/type :mutation
:operation/name "UpsertTransactionRule"}
:venia/queries [{:query/data [:upsert-transaction-rule
{:transaction-rule (-> data
(select-keys [:id
:description
:amount-lte
:amount-gte
:note])
(assoc :client-id (:id (:client data)))
(assoc :bank-account-id (:id (:bank-account data))))}
default-read]}]}))
;; EVENTS
(re-frame/reg-event-db
::adding
(fn [db [_ new]]
(-> db (forms/start-form ::form (assoc new
:description nil)))))
(re-frame/reg-event-db
::editing
(fn [db [_ which]]
(-> db (forms/start-form ::form {}))))
(re-frame/reg-event-db
::changed
(forms/change-handler ::form
(fn [data field value]
[])))
(re-frame/reg-event-fx
::saving
[with-user (forms/triggers-loading ::form) (forms/in-form ::form)]
(fn [{:keys [user] {:keys [data]} :db} [_ params]]
{:graphql
{:token user
:query-obj @(re-frame/subscribe [::query])
:on-success [::succeeded params]
:on-error [::forms/save-error ::form]}}))
(re-frame/reg-event-fx
::succeeded
[(forms/triggers-stop ::form)]
(fn [{:keys [db]} [_ {:keys [rule-saved]} result]]
{:db (forms/start-form db ::form {:client @(re-frame/subscribe [::subs/client])})
:dispatch (conj rule-saved (:upsert-transaction-rule result))}))
;; VIEWS
(def rule-form (forms/vertical-form {:can-submit [::can-submit]
:change-event [::changed]
:submit-event [::saving ]
:id ::form}))
(defn form [{:keys [can-change-amount?] :as params}]
[layouts/side-bar {:on-close (dispatch-event [::forms/form-closing ::form ])}
(let [{:keys [data active? error id]} @(re-frame/subscribe [::forms/form ::form])
{:keys [form field raw-field error-notification submit-button ]} rule-form
exists? (:id data)
chooseable-expense-accounts @(re-frame/subscribe [::subs/chooseable-expense-accounts])
accounts-by-id @(re-frame/subscribe [::subs/accounts-for-client-by-id])]
^{:key id}
[form (assoc params :title "New Invoice")
(when-not @(re-frame/subscribe [::subs/client])
[field "Client"
[typeahead-entity {:matches @(re-frame/subscribe [::subs/clients])
:match->text :name
:type "typeahead-entity"
:auto-focus (if @(re-frame/subscribe [::subs/client]) false true)
:field [:client]
:spec ::entity/client}]])
[field "Bank account"
[typeahead-entity {:matches @(re-frame/subscribe [::subs/real-bank-accounts-for-client (:client data)])
:match->text :name
:auto-focus (if @(re-frame/subscribe [::subs/client]) true false)
:type "typeahead-entity"
:field [:bank-account]
:spec ::entity/bank-account}]]
[field "Description"
[:input.input {:type "text"
:field [:description]
:spec ::entity/description}]]
[:div.field
[:p.help "Amount"]
[:div.control
[:div.columns
[:div.column
[raw-field
[:input.input {:type "number"
:placeholder ">="
:field [:amount-gte]
:spec ::entity/amount-gte
:step "0.01"}]]]
[:div.column
[raw-field
[:input.input {:type "number"
:placeholder "<="
:field [:amount-lte]
:spec ::entity/amount-lte
:step "0.01"}]]]]]]
[field "Note"
[:input.input {:type "text"
:field [:note]
:spec ::entity/note}]]
[error-notification]
[submit-button "Save"]])])

View File

@@ -1,5 +1,76 @@
(ns auto-ap.views.pages.admin.rules.table)
(ns auto-ap.views.pages.admin.rules.table
(:require [auto-ap.subs :as subs]
[auto-ap.views.components.paginator :refer [paginator]]
[auto-ap.views.components.sorter :refer [sorted-column]]
[re-frame.core :as re-frame]))
(defn table [{:keys [id rule-page on-params-change params status]}]
(let [opc (fn [p]
(on-params-change (merge @params p )))]
(fn [{:keys [id rule-page on-params-change params status]}]
(let [{:keys [sort-by asc]} @params
{:keys [transaction-rules start end count total]} @rule-page
selected-client @(re-frame/subscribe [::subs/client])]
[:div
[paginator {:start start :end end :count count :total total
:on-change (fn [p ]
(on-params-change (merge @params p)))}]
[:table.table.is-fullwidth.compact
[:thead
[:tr
[sorted-column {:on-sort opc
:style {:width "25%" :cursor "pointer"}
:sort-key "client"
:sort-by sort-by
:asc asc}
"Client"]
(defn table [x]
[:div])
[sorted-column {:on-sort opc
:style {:width "25%" :cursor "pointer"}
:sort-key "bank-account"
:sort-by sort-by
:asc asc}
"Bank Account"]
[sorted-column {:on-sort opc
:style {:width "25%" :cursor "pointer"}
:sort-key "description"
:sort-by sort-by
:asc asc}
"Description"]
[sorted-column {:on-sort opc
:style {:width "8em" :cursor "pointer"}
:class "has-text-right"
:sort-key "amount-gte"
:sort-by sort-by
:asc asc}
">="]
[sorted-column {:on-sort opc
:class "has-text-right"
:style {:width "8em" :cursor "pointer"}
:sort-key "amount-lte"
:sort-by sort-by
:asc asc}
"<="]
[sorted-column {:on-sort opc
:style {:width "25%" :cursor "pointer"}
:sort-key "note"
:sort-by sort-by
:asc asc}
"Note"]]]
[:tbody
(if (:loading @status)
[:tr
[:td {:col-span 5}
[:i.fa.fa-spin.fa-spinner]]]
(for [{:keys [client bank-account description amount-lte amount-gte note] :as r} transaction-rules]
^{:key id}
[:tr {:class (:class r)}
[:td (:name client)]
[:td (:name bank-account)]
[:td description]
[:td.has-text-right amount-gte ]
[:td.has-text-right amount-lte]
[:td note]]))]]]))))