From b98d00a1969a40ebc96658cd2e2b2dd959b54cc2 Mon Sep 17 00:00:00 2001 From: Bryce Covert Date: Thu, 31 May 2018 18:43:12 -0700 Subject: [PATCH] started on expense accounts. --- ...04-DOWN-create-default-expense-account.sql | 5 +++ ...4504-UP-create-default-expense-account.sql | 5 +++ resources/public/index.html | 3 +- .../auto_ap/db/invoices_expense_accounts.clj | 31 +++++++++++++++++++ src/clj/auto_ap/db/vendors.clj | 1 + src/clj/auto_ap/graphql.clj | 22 ++++++++++++- src/clj/auto_ap/graphql/expense_accounts.clj | 9 ++++++ src/clj/auto_ap/graphql/invoices.clj | 6 ++++ src/clj/auto_ap/routes/invoices.clj | 3 ++ src/cljc/auto_ap/entities/vendors.cljc | 2 ++ src/cljc/auto_ap/expense_accounts.cljc | 2 +- src/cljs/auto_ap/events.cljs | 4 +-- .../views/components/invoice_table.cljs | 23 ++++++++++++-- .../auto_ap/views/pages/admin/vendors.cljs | 24 +++++++++++--- 14 files changed, 128 insertions(+), 12 deletions(-) create mode 100644 migrator/migrations/1527534504-DOWN-create-default-expense-account.sql create mode 100644 migrator/migrations/1527534504-UP-create-default-expense-account.sql create mode 100644 src/clj/auto_ap/db/invoices_expense_accounts.clj create mode 100644 src/clj/auto_ap/graphql/expense_accounts.clj diff --git a/migrator/migrations/1527534504-DOWN-create-default-expense-account.sql b/migrator/migrations/1527534504-DOWN-create-default-expense-account.sql new file mode 100644 index 00000000..1ee59910 --- /dev/null +++ b/migrator/migrations/1527534504-DOWN-create-default-expense-account.sql @@ -0,0 +1,5 @@ +-- 1527534504 DOWN create-default-expense-account + +alter table vendors drop column default_expense_account; + +drop table invoices_expense_accounts; diff --git a/migrator/migrations/1527534504-UP-create-default-expense-account.sql b/migrator/migrations/1527534504-UP-create-default-expense-account.sql new file mode 100644 index 00000000..b8ce09eb --- /dev/null +++ b/migrator/migrations/1527534504-UP-create-default-expense-account.sql @@ -0,0 +1,5 @@ +-- 1527534504 UP create-default-expense-account + +alter table vendors add column default_expense_account INT; + +create table invoices_expense_accounts (id serial primary key, invoice_id int references invoices(id), expense_account_id int not null, amount decimal not null); diff --git a/resources/public/index.html b/resources/public/index.html index 93ed9c7c..93c92623 100644 --- a/resources/public/index.html +++ b/resources/public/index.html @@ -281,7 +281,8 @@ width: 100%; top: 100%; left: 0; - z-index: 1000; + z-index: 10000; + overflow: visible; float: left; min-width: 160px; padding: 5px 0; diff --git a/src/clj/auto_ap/db/invoices_expense_accounts.clj b/src/clj/auto_ap/db/invoices_expense_accounts.clj new file mode 100644 index 00000000..f9df0e5a --- /dev/null +++ b/src/clj/auto_ap/db/invoices_expense_accounts.clj @@ -0,0 +1,31 @@ +(ns auto-ap.db.invoices-expense-accounts + (:require [honeysql.core :as sql] + [clojure.java.jdbc :as j] + [auto-ap.db.utils :refer [clj->db kebab->snake db->clj get-conn query] :as utils] + [honeysql.helpers :as helpers])) +(defn get-missing [] + (query {:select [:i.id :v.default-expense-account :i.total] + :from [[:invoices :i]] + :join [[:vendors :v] + [:= :v.id :i.vendor-id]] + :left-join [[:invoices-expense-accounts :nonexist] + [:= :i.id :nonexist.invoice-id]] + :where [:and [:= :nonexist.id nil] + [:not= :v.default-expense-account nil]] })) + +(defn get-for-invoice [id] + (query {:select [:*] + :from [:invoices-expense-accounts] + :where [:= :invoice-id id]})) + +(defn assign-defaults! [] + (j/db-do-prepared (get-conn) + (sql/format {:insert-into [[:invoices-expense-accounts [:invoice-id :expense-account-id :amount]] + {:select [:i.id :v.default-expense-account :i.total] + :from [[:invoices :i]] + :join [[:vendors :v] + [:= :v.id :i.vendor-id]] + :left-join [[:invoices-expense-accounts :nonexist] + [:= :i.id :nonexist.invoice-id]] + :where [:and [:= :nonexist.id nil] + [:not= :v.default-expense-account nil]] }] }))) diff --git a/src/clj/auto_ap/db/vendors.clj b/src/clj/auto_ap/db/vendors.clj index 2f4e0aee..b0d32175 100644 --- a/src/clj/auto_ap/db/vendors.clj +++ b/src/clj/auto_ap/db/vendors.clj @@ -22,6 +22,7 @@ :secondary-contact :secondary-email :secondary-phone + :default-expense-account :data]) (defn unparse [x] diff --git a/src/clj/auto_ap/graphql.clj b/src/clj/auto_ap/graphql.clj index f37c58d1..ef8f0a1c 100644 --- a/src/clj/auto_ap/graphql.clj +++ b/src/clj/auto_ap/graphql.clj @@ -13,6 +13,7 @@ [auto-ap.db.checks :as checks] [auto-ap.routes.checks :as rchecks] [auto-ap.graphql.users :as gq-users] + [auto-ap.graphql.expense-accounts :as expense-accounts] [auto-ap.graphql.invoices :as gq-invoices] [auto-ap.db.reminders :as reminders] [auto-ap.db.invoices-checks :as invoices-checks] @@ -43,6 +44,7 @@ :vendor {:fields {:id {:type 'Int} :name {:type 'String} + :default_expense_account {:type 'Int} :invoice_reminder_schedule {:type 'String}}} :reminder {:fields {:id {:type 'Int} @@ -74,11 +76,26 @@ :companies {:type '(list :company) :resolve :get-user-companies}}} + :expense_account {:fields {:id {:type 'Int} + :name {:type 'String} + :parent {:type :expense_account + :resolve :get-expense-account-parent}}} + + :invoices_expense_accounts + {:fields {:id {:type 'Int} + :invoice_id {:type 'Int} + :expense_account_id {:type 'Int} + :expense_account {:type :expense_account + :resolve :get-expense-account} + :amount {:type 'String}}} + :invoice {:fields {:id {:type 'Int} :total {:type 'String} :outstanding_balance {:type 'String} :invoice_number {:type 'String} + :expense_accounts {:type '(list :invoices_expense_accounts) + :resolve :get-invoices-expense-accounts} :date {:type 'String} :company_id {:type 'Int} :checks {:type '(list :invoice_check) @@ -303,13 +320,16 @@ :get-company-for-invoice get-company-for-invoice :get-invoices-checks get-invoices-checks :get-check-by-id get-check-by-id + :get-invoices-expense-accounts gq-invoices/get-invoices-expense-accounts :get-company get-company :get-user get-user :get-user-companies get-user-companies :mutation/print-checks print-checks :mutation/edit-user gq-users/edit-user :mutation/add-invoice gq-invoices/add-invoice - :get-vendor get-vendor}) + :get-vendor get-vendor + :get-expense-account expense-accounts/get-expense-account + :get-expense-account-parent expense-accounts/get-parent}) schema/compile)) diff --git a/src/clj/auto_ap/graphql/expense_accounts.clj b/src/clj/auto_ap/graphql/expense_accounts.clj new file mode 100644 index 00000000..1092c8da --- /dev/null +++ b/src/clj/auto_ap/graphql/expense_accounts.clj @@ -0,0 +1,9 @@ +(ns auto-ap.graphql.expense-accounts + (:require [auto-ap.graphql.utils :refer [->graphql]] + [auto-ap.expense-accounts :as expense-accounts])) + +(defn get-expense-account [context args value] + (->graphql (expense-accounts/expense-accounts (:expense_account_id value)))) + +(defn get-parent [context args value] + (->graphql (expense-accounts/expense-accounts (:parent value)))) diff --git a/src/clj/auto_ap/graphql/invoices.clj b/src/clj/auto_ap/graphql/invoices.clj index 30be9d48..6782dc09 100644 --- a/src/clj/auto_ap/graphql/invoices.clj +++ b/src/clj/auto_ap/graphql/invoices.clj @@ -1,6 +1,7 @@ (ns auto-ap.graphql.invoices (:require [auto-ap.graphql.utils :refer [->graphql]] [auto-ap.db.invoices :as invoices] + [auto-ap.db.invoices-expense-accounts :as invoices-expense-accounts] [auto-ap.time :refer [parse normal-date]])) (defn add-invoice [context {{:keys [total invoice_number company_id vendor_id date] :as in} :invoice} value] @@ -15,3 +16,8 @@ :date (parse date normal-date)}]) (first) (->graphql))) + + +(defn get-invoices-expense-accounts [context args value] + (->graphql + (invoices-expense-accounts/get-for-invoice (:id value)))) diff --git a/src/clj/auto_ap/routes/invoices.clj b/src/clj/auto_ap/routes/invoices.clj index 595080ea..26b0909b 100644 --- a/src/clj/auto_ap/routes/invoices.clj +++ b/src/clj/auto_ap/routes/invoices.clj @@ -6,6 +6,7 @@ [auto-ap.utils :refer [by]] [auto-ap.parse :as parse] [auto-ap.routes.utils :refer [wrap-secure]] + [auto-ap.db.invoices-expense-accounts :as expense-accounts] [compojure.core :refer [GET POST context defroutes wrap-routes]] [clojure.string :as str])) @@ -138,7 +139,9 @@ inserted-row-count (invoices/upsert-multi! insert-rows) already-imported-count (- (count insert-rows) inserted-row-count) + ] + (expense-accounts/assign-defaults!) diff --git a/src/cljc/auto_ap/entities/vendors.cljc b/src/cljc/auto_ap/entities/vendors.cljc index eeebd761..b71851c1 100644 --- a/src/cljc/auto_ap/entities/vendors.cljc +++ b/src/cljc/auto_ap/entities/vendors.cljc @@ -24,6 +24,7 @@ (s/def ::secondary-email ::email) (s/def ::secondary-phone ::phone) (s/def ::address ::address/address) +(s/def ::default-expense-account int?) (s/def ::code (s/nilable string?)) @@ -38,6 +39,7 @@ ::secondary-email ::secondary-phone ::address + ::default-expense-account ])) diff --git a/src/cljc/auto_ap/expense_accounts.cljc b/src/cljc/auto_ap/expense_accounts.cljc index f223c825..1c0f1488 100644 --- a/src/cljc/auto_ap/expense_accounts.cljc +++ b/src/cljc/auto_ap/expense_accounts.cljc @@ -1,6 +1,6 @@ (ns auto-ap.expense-accounts) -(def accounts +(def expense-accounts {5110 {:name "Food Cost" :parent nil} 5111 {:name "Proteins Cost" :parent 5110} 5112 {:name "Beef/ Pork Costs" :parent 5111} diff --git a/src/cljs/auto_ap/events.cljs b/src/cljs/auto_ap/events.cljs index b5452f17..a4549dd6 100644 --- a/src/cljs/auto_ap/events.cljs +++ b/src/cljs/auto_ap/events.cljs @@ -38,7 +38,7 @@ :query-obj {:venia/queries [[:company [:id :name [:bank-accounts [:id :number :check-number :name]]]] [:vendor - [:id :name]]]} + [:id :name :default-expense-account]]]} :on-success [::received-initial]}})))) @@ -54,7 +54,7 @@ :query-obj {:venia/queries [[:company [:id :name [:bank-accounts [:id :number :check-number :name]]]] [:vendor - [:id :name]]]} + [:id :name :default-expense-account]]]} :on-success [::received-initial]} :db (assoc db :user (assoc user :token token))})) diff --git a/src/cljs/auto_ap/views/components/invoice_table.cljs b/src/cljs/auto_ap/views/components/invoice_table.cljs index 14f6981f..aac7be56 100644 --- a/src/cljs/auto_ap/views/components/invoice_table.cljs +++ b/src/cljs/auto_ap/views/components/invoice_table.cljs @@ -20,7 +20,13 @@ {:venia/queries [[:invoice_page (assoc params :company-id (:id @(re-frame/subscribe [::subs/company]))) - [[:invoices [:id :total :outstanding-balance :invoice-number :date [:vendor [:name :id]] [:company [:name :id]] [:checks [:amount [:check [:amount :s3_url :check_number ]]]]]] + [[:invoices [:id :total :outstanding-balance :invoice-number :date + [:vendor [:name :id]] + [:expense_accounts [:amount :id + [:expense_account [:id :name [:parent [:id :name]]]]]] + [:company [:name :id]] + [:checks [:amount [:check [:amount :s3_url :check_number ]]]] + ]] :total :start :end]]]}) @@ -76,19 +82,27 @@ :sort-by sort-by :asc asc} "Amount"] + [sorted-column {:on-sort opc :style {:width "10em" :cursor "pointer"} :sort-key "outstanding" :sort-by sort-by :asc asc} - "Outstanding"] + "Outstanding"] + + [sorted-column {:on-sort opc + :style {:width "8em" :cursor "pointer"} + :sort-key "total" + :sort-by sort-by + :asc asc} + "Expense Accounts"] [:th {:style {:width "10em"}} "" ]]] [:tbody (if (:loading @status) [:tr [:td {:col-span 5} [:i.fa.fa-spin.fa-spinner]]] - (for [{:keys [company checks invoice-number date total outstanding-balance id vendor] :as i} (:invoices @invoice-page)] + (for [{:keys [company checks expense-accounts invoice-number date total outstanding-balance id vendor] :as i} (:invoices @invoice-page)] ^{:key id} [:tr {:class (:class i)} (when check-boxes @@ -105,6 +119,9 @@ [:td (gstring/format "$%.2f" total )] [:td (gstring/format "$%.2f" outstanding-balance )] + [:td (for [e expense-accounts] + ^{:key (:id e)} + [:a.tag (:name (:expense-account e)) " "(gstring/format "$%.2f" (:amount e) ) ])] [:td (for [check checks] ^{:key (:id check)} [:a.tag {:href (:s3-url (:check check)) :target "_new"} [:i.fa.fa-money-check] [:span.icon [:i.fa.fa-money]] (str " " (:check-number (:check check)) " (" (gstring/format "$%.2f" (:amount check) ) ")")])]]))]]])))) diff --git a/src/cljs/auto_ap/views/pages/admin/vendors.cljs b/src/cljs/auto_ap/views/pages/admin/vendors.cljs index a3555a80..edb30589 100644 --- a/src/cljs/auto_ap/views/pages/admin/vendors.cljs +++ b/src/cljs/auto_ap/views/pages/admin/vendors.cljs @@ -10,6 +10,9 @@ [auto-ap.views.components.modal :refer [modal]] [clojure.spec.alpha :as s] [auto-ap.views.utils :refer [login-url dispatch-value-change dispatch-event bind-field horizontal-field]] + + [auto-ap.views.components.typeahead :refer [typeahead]] + [auto-ap.expense-accounts :refer [expense-accounts]] [cljs.reader :as edn] [auto-ap.routes :as routes] [bidi.bidi :as bidi])) @@ -187,13 +190,26 @@ :event ::events/change :subscription editing-vendor}]] " Never"]]] + + [:h2.subtitle "Expense Accounts"] + [horizontal-field + [:label.label "Default"] + [bind-field + [typeahead {:matches (map (fn [[k v]] [k (:name v)]) expense-accounts) + :type "typeahead" + :field [:default-expense-account] + :spec ::entity/default-expense-account + :event ::events/change + :subscription editing-vendor}]]] + + - [:h2.subtitle "Clients"] + #_[:h2.subtitle "Clients"] - [horizontal-field + #_[horizontal-field nil - [:div.control + [:div.control@(re-frame/subscribe [::subs/exp]) [:div.select.is-expanded [bind-field [:select {:type "select" @@ -214,7 +230,7 @@ {:on-click (dispatch-event [::events/add-relationship])} [:span.icon [:i.fa.fa-plus]]]]] - [horizontal-field + #_[horizontal-field nil [:ul (for [[i r] (map vector (range) (:relationships editing-vendor))]