diff --git a/src/clj/auto_ap/datomic/ledger.clj b/src/clj/auto_ap/datomic/ledger.clj index fe483f68..98efb69a 100644 --- a/src/clj/auto_ap/datomic/ledger.clj +++ b/src/clj/auto_ap/datomic/ledger.clj @@ -67,6 +67,12 @@ '[?li :journal-entry-line/account ?a]]} :args [(:bank-account-id args)]}) + (:account-id args) + (merge-query {:query {:in ['?a2] + :where ['[?e :journal-entry/line-items ?li2] + '[?li2 :journal-entry-line/account ?a2]]} + :args [(:account-id args)]}) + (:to-numeric-code args) (merge-query {:query {:in ['?to-numeric-code] :where ['[?e :journal-entry/line-items ?li] diff --git a/src/clj/auto_ap/graphql.clj b/src/clj/auto_ap/graphql.clj index f3670b3c..f680f5f1 100644 --- a/src/clj/auto_ap/graphql.clj +++ b/src/clj/auto_ap/graphql.clj @@ -460,6 +460,7 @@ :ledger_page {:type :ledger_page :args {:client_id {:type :id} :vendor_id {:type :id} + :account_id {:type :id} :bank_account_id {:type :id} :date_range {:type :date_range} :location {:type 'String} diff --git a/src/clj/auto_ap/graphql/checks.clj b/src/clj/auto_ap/graphql/checks.clj index 3e88b4f8..ebb9975f 100644 --- a/src/clj/auto_ap/graphql/checks.clj +++ b/src/clj/auto_ap/graphql/checks.clj @@ -116,12 +116,14 @@ (into [:cell {:colspan 9}] (let [{:keys [:client/name] - {:keys [:address/street1 :address/city :address/state :address/zip ]} :client/address} client] - (list - [:paragraph " " name] - [:paragraph " " street1] - [:paragraph " " city ", " state " " zip] - ))) + {:keys [:address/street1 :address/street2 :address/city :address/state :address/zip ]} :client/address} client] + (filter identity + (list + [:paragraph " " name] + [:paragraph " " street1] + (when (not (str/blank? street2)) + [:paragraph " " street2]) + [:paragraph " " city ", " state " " zip])))) [:cell {:colspan 2 :size 13} check]] @@ -131,6 +133,9 @@ [:cell {:colspan 5} [:paragraph " " vendor-name "\n" " " (:address/street1 (:vendor/address vendor)) "\n" + (when (not (str/blank? (:address/street2 (:vendor/address vendor)))) + (str " " (:address/street2 (:vendor/address vendor)) "\n") + ) " " (:address/city (:vendor/address vendor)) ", " (:address/state (:vendor/address vendor)) " " (:address/zip (:vendor/address vendor))]] [:cell {:align :right} "Paid to:\n" diff --git a/src/clj/auto_ap/graphql/ledger.clj b/src/clj/auto_ap/graphql/ledger.clj index 1949d3f3..5a9717ff 100644 --- a/src/clj/auto_ap/graphql/ledger.clj +++ b/src/clj/auto_ap/graphql/ledger.clj @@ -104,8 +104,9 @@ [comparable-results] (l/get-graphql {:client-id (:client_id args) - :to-date (coerce/to-date (time/minus (:date args) (time/years 1))) + :date-range {:end (coerce/to-date (time/minus (:date args) (time/years 1)))} :count Integer/MAX_VALUE})] + (println "count" (take 3 comparable-results)) (->graphql {:balance-sheet-accounts (roll-up client results) :comparable-balance-sheet-accounts (roll-up client comparable-results)}))) diff --git a/src/clj/auto_ap/parse/csv.clj b/src/clj/auto_ap/parse/csv.clj index 9ae43913..86a884fa 100644 --- a/src/clj/auto_ap/parse/csv.clj +++ b/src/clj/auto_ap/parse/csv.clj @@ -45,6 +45,10 @@ (comp (drop 1) (map (fn [row] (into {} (map vector header row)))) + (filter (fn [row] + (and (not (str/blank? (get row "Invoice Date"))) + (not (str/blank? (get row "Orig Amt"))) + (not (str/blank? (get row "Inv #")))))) (map (fn [row] {:vendor-code nil :customer-identifier nil diff --git a/src/clj/auto_ap/parse/templates.clj b/src/clj/auto_ap/parse/templates.clj index 17ea6309..48171244 100644 --- a/src/clj/auto_ap/parse/templates.clj +++ b/src/clj/auto_ap/parse/templates.clj @@ -176,15 +176,15 @@ ;; Young's Market Co new statement {:vendor "Youngs Market" - :keywords [#"YOUNG'S MARKET COMPANY"] + :keywords [#"(YOUNG'S MARKET COMPANY|Young.*Statement)"] :extract {:date #"([0-9]+/[0-9]+/[0-9]+)" - :customer-identifier #"SHIP TO SITE: ([\w ]+)" - :invoice-number #"^([0-9]+)" - :total #"\$([0-9\.,]+)"} + :customer-identifier #"Customer Name +([\w ]+)" + :invoice-number #"\s{2,}([0-9]+)" + :total #"\$?([0-9,]+\.[0-9]+)"} :parser {:date [:clj-time "MM/dd/yyyy"] :total [:trim-commas nil]} :multi #"\n" - :multi-match? #"^[0-9]+"} + :multi-match? #"^[0-9]+.*\$?([0-9,]+\.[0-9]+).*\$?([0-9,]+\.[0-9]+)"} ;; Young's Market Co - INVOICE {:vendor "Youngs Market" diff --git a/src/cljs/auto_ap/views/pages/ledger.cljs b/src/cljs/auto_ap/views/pages/ledger.cljs index f466c249..81a508ce 100644 --- a/src/cljs/auto_ap/views/pages/ledger.cljs +++ b/src/cljs/auto_ap/views/pages/ledger.cljs @@ -39,7 +39,6 @@ :<- [::side-bar/filter-params] :<- [::table/table-params] (fn [[last-params client filter-params table-params]] - (println "HERE?") (let [params (cond-> {} client (assoc :client-id (:id client)) (seq filter-params) (merge filter-params) @@ -76,7 +75,8 @@ :total :start :end]]]} - :on-success [::received]}})) + :on-success [::received]} + :set-uri-params (dissoc params :status :client-id)})) (re-frame/reg-event-fx ::unmounted diff --git a/src/cljs/auto_ap/views/pages/ledger/profit_and_loss.cljs b/src/cljs/auto_ap/views/pages/ledger/profit_and_loss.cljs index 1d69afd1..2fd2ebb6 100644 --- a/src/cljs/auto_ap/views/pages/ledger/profit_and_loss.cljs +++ b/src/cljs/auto_ap/views/pages/ledger/profit_and_loss.cljs @@ -9,11 +9,12 @@ [cljs-time.core :as t] [re-frame.core :as re-frame])) (def ranges - {:sales [41000 48999] - :cogs [51000 59999] - :payroll [60100 62999] - :controllable [71000 79999] - :noncontrollable [81000 99999]}) + {:sales [40000 48999] + :cogs [50000 59999] + :payroll [60000 62999] + :controllable [70000 79999] + :fixed-overhead [80000 89999] + :ownership-controllable [90000 99999]}) ;; SUBS (re-frame/reg-sub @@ -31,7 +32,9 @@ (filter identity) (set) - (sort)))) + (sort-by (fn [x] (if (= x "HQ" ) + "ZZZZZZ" + x)))))) (re-frame/reg-sub ::report @@ -78,7 +81,7 @@ (filter (fn [{:keys [account-type location numeric-code]}] (and (or (nil? only-location) (= only-location location)) - (< (get-in ranges [type 0]) numeric-code (get-in ranges [type 1]))))) + (<= (get-in ranges [type 0]) numeric-code (get-in ranges [type 1]))))) (sort-by :numeric-code)))) @@ -94,7 +97,7 @@ (filter (fn [{:keys [account-type location numeric-code]}] (and (or (nil? only-location) (= only-location location)) - (< (get-in ranges [type 0]) numeric-code (get-in ranges [type 1]))))) + (<= (get-in ranges [type 0]) numeric-code (get-in ranges [type 1]))))) (by :id)))) (re-frame/reg-sub @@ -107,7 +110,7 @@ (filter (fn [{:keys [account-type location numeric-code]}] (and (or (nil? only-location) (= only-location location)) - (< (get-in ranges [type 0]) numeric-code (get-in ranges [type 1]))))) + (<= (get-in ranges [type 0]) numeric-code (get-in ranges [type 1]))))) (by :id)))) (re-frame/reg-event-db @@ -227,45 +230,41 @@ standard))})]})) (def groupings - {:sales [["4000-4099 HQ Income" 4000 4099] - ["4100-4200 Food Sales" 4100 4399] - ["4400-4600 Alcohol Sales" 4400 4699] - ["4700 Merchandise Sales" 4700 4799] - ["4800 Other Operating Income" 4800 4999]] - :cogs [["5000-5099 Unassigned COGS" 5000 5099] - ["5100-5200 Food Costs" 5100 5399] - ["5400-5600 Alcohol Cost" 5400 5699] - ["5700 Merchandise Cost" 5700 5799] - ["5800 Other Operating Cost" 5800 5899] - ["5900 Paper Cost" 5900 5999]] - :payroll [["6010 HQ Payroll" 6000 6029] - ["6030 Payroll Benefits and Taxes" 6030 6099] - ["6100 Management Payroll" 6100 6199] - ["6200 Staff Payroll" 6200 6999]] + {:sales [["40000-43999 Food Sales " 40000 43999] + ["44000-46999 Alcohol Sales" 44000 46999] + ["47000 Merchandise Sales" 47000 47999] + ["48000 Other Operating Income" 48000 48999] + ["49000 Non-Business Income" 49000 49999]] + :cogs [ + ["50000-54000 Food Costs" 50000 53999] + ["54000-56000 Alcohol Costs" 54000 55999] + ["56000 Merchandise Costs" 56000 56999] + ["57000-60000 Other Costs of Sales" 57000 59999]] + :payroll [["60000 Payroll - General" 60000 60999] + ["61000 Payroll - Management" 61000 61999] + ["62000 Payroll - BOH" 62000 62999] + ["63000-66000 Payroll - FOH" 63000 65999] + ["66000-70000 Payroll - Other" 66000 69999]] - :controllable [["7100 Ops Related DirGMC Exp" 7000 7199] - ["7200 Customer Related DirGMC Exp" 7200 7299] - ["7300 Employee Related DirGMC Exp" 7300 7399] - ["7400 Building and Equipment Related DirGMC Exp" 7400 7499] - ["7500 Office/ Management Related DirGMC Exp" 7500 7599] - ["7600 Other Controllable DirGMC Exp" 7600 7999]] + :controllable [["70000 72000 GM Controllable Costs - Ops Related" 70000 71999] + ["72000 GM Controllable Costs - Customer Related" 72000 72999] + ["73000 GM Controllable Costs - Employee Related" 73000 73999] + ["74000 GM Controllable Costs - Building & Equipment Related" 74000 74999] + ["75000 GM Controllable Costs - Office & Management Related" 75000 75999] + ["76000-80000 GM Controllable Costs - Other" 76000 79999]] - :noncontrollable [["8100 Operational" 8000 8199] - ["8200 Occupancy Costs" 8200 8299] - ["8300 Utilities" 8300 8399] - ["8400 Equipment Rental" 8400 8499] - ["8500-8700 Taxes and Insurance" 8500 8799] - ["8800 Depreciation" 8800 8899] - ["8900 Other Non-Controllable" 8900 8999] - ["9100 Promotion and Outreach" 9000 9199] - ["9200 Employee Morale and Training" 9200 9299] - ["9300 Operational" 9300 9499] - ["9500 Interest and Bank Expenses" 9500 9599] - ["9600 Depreciation" 9600 9699] - ["9700 Taxes" 9700 9799] - ["9800 Other Expenses" 9800 9899] - ;; ["9900 Tax Only Expenses" 9900 9999] Excluded from Profit and loss - ]}) + :fixed-overhead [["80000-82000 Operational Costs" 80000 81999] + ["82000 Occupancy Costs" 82000 82999] + ["83000 Utility Costs" 83000 83999] + ["84000 Equipment Rental" 84000 84999] + ["85000-87000 Taxes & Insurance" 85000 86999] + ["87000-90000 Other Non-Controllable Costs" 87000 89999]] + :ownership-controllable [["90000-93000 Research & Entertainment" 90000 92999] + ["93000 Bank Charges & Interest" 93000 93999] + ["94000-96000 Other Owner Controllable Costs" 94000 95999] + ["96000 Depreciation" 96000 96999] + ["97000 Taxes" 97000 97999] + ["98000 Other Expenses" 98000 98999]]}) @@ -509,10 +508,11 @@ (subtotal [:payroll :cogs] #{} (str location " Prime Costs") location) (subtotal [:sales :payroll :cogs] #{:payroll :cogs} (str location " Gross Profits") location) (overall-grouping :controllable (str location " Controllable Expenses") location) - (overall-grouping :noncontrollable (str location " Noncontrallable Expenses") location) - (subtotal [:controllable :noncontrollable] #{} (str location " Overhead") location) - (subtotal [:sales :cogs :payroll :controllable :noncontrollable] #{:cogs :payroll :controllable :noncontrollable} (str location " Net Income") location) - (subtotal [:sales :cogs :payroll :controllable :noncontrollable] #{:cogs :payroll :controllable :noncontrollable} "Net Income" nil))))]])]))) + (overall-grouping :fixed-overhead (str location " Fixed Overhead") location) + (overall-grouping :ownership-controllable (str location " Ownership Controllable") location) + (subtotal [:controllable :fixed-overhead :ownership-controllable] #{} (str location " Overhead") location) + (subtotal [:sales :cogs :payroll :controllable :fixed-overhead :ownership-controllable] #{:cogs :payroll :controllable :fixed-overhead :ownership-controllable} (str location " Net Income") location) + (subtotal [:sales :cogs :payroll :controllable :fixed-overhead :ownership-controllable] #{:cogs :payroll :controllable :fixed-overhead :ownership-controllable} "Net Income" nil))))]])]))) {:component-will-mount #(re-frame/dispatch-sync [::params-change {:from-date (date->str (t/minus (local-now) (t/period :years 1)) standard) :to-date (date->str (local-now) standard)}]) })) diff --git a/src/cljs/auto_ap/views/pages/ledger/side_bar.cljs b/src/cljs/auto_ap/views/pages/ledger/side_bar.cljs index 07ed6e2e..07439d89 100644 --- a/src/cljs/auto_ap/views/pages/ledger/side_bar.cljs +++ b/src/cljs/auto_ap/views/pages/ledger/side_bar.cljs @@ -9,10 +9,38 @@ [re-frame.core :as re-frame])) (re-frame/reg-sub - ::filters + ::specific-filters (fn [db ] (::filters db {}))) +(re-frame/reg-sub + ::filters + :<- [::specific-filters] + :<- [::subs/vendors-by-id] + :<- [::subs/bank-accounts-by-id] + :<- [::subs/accounts-by-id] + :<- [::subs/query-params] + (fn [[specific-filters vendors-by-id bank-accounts-by-id accounts-by-id query-params] ] + (let [url-filters (-> query-params + (select-keys #{:vendor-id + :bank-account-id + :account-id + :date-range})) + url-filters {:vendor (when-let [vendor-id (:vendor-id url-filters)] + {:id (str vendor-id) + :name (get-in vendors-by-id [(str vendor-id) :name] "Loading...")}) + :bank-account (when-let [bank-account-id (:bank-account-id url-filters)] + {:id (str bank-account-id) + :name (get-in bank-accounts-by-id [(str bank-account-id) :name] "Loading...")}) + + :account (when-let [account-id (:account-id url-filters)] + {:id (str account-id) + :numeric-code (get-in accounts-by-id [(str account-id) :numeric-code] "Loading...") + :name (get-in accounts-by-id [(str account-id) :name] "Loading...")}) + :date-range (:date-range url-filters)}] + (println url-filters specific-filters) + (merge url-filters specific-filters )))) + (re-frame/reg-sub ::filter :<- [::filters] @@ -24,6 +52,7 @@ :<- [::filters] (fn [filters] {:vendor-id (:id (:vendor filters)) + :account-id (:id (:account filters)) :date-range (:date-range filters) :bank-account-id (:id (:bank-account filters))})) @@ -39,7 +68,8 @@ (defn ledger-side-bar [] (let [ap @(re-frame/subscribe [::subs/active-page]) - user @(re-frame/subscribe [::subs/user])] + user @(re-frame/subscribe [::subs/user]) + accounts @(re-frame/subscribe [::subs/accounts])] [:div [:ul.menu-list [:li.menu-item @@ -69,10 +99,11 @@ [:div [:p.menu-label "Bank Account"] [:div - [bank-account-filter - {:on-change-event [::filter-changed :bank-account] - :value @(re-frame/subscribe [::filter :bank-account]) - :bank-accounts @(re-frame/subscribe [::subs/bank-accounts])}]] + [typeahead-entity {:matches @(re-frame/subscribe [::subs/bank-accounts]) + :match->text :name + :type "typeahead-entity" + :on-change #(re-frame/dispatch [::filter-changed :bank-account %]) + :value @(re-frame/subscribe [::filter :bank-account])}]] [:p.menu-label "Vendor"] [:div @@ -81,6 +112,14 @@ :match->text :name :type "typeahead-entity" :value @(re-frame/subscribe [::filter :vendor])}]] + + [:p.menu-label "Account"] + [:div + [typeahead-entity {:matches accounts + :match->text (fn [x ] (str (:numeric-code x) " - " (:name x))) + :type "typeahead-entity" + :on-change #(re-frame/dispatch [::filter-changed :account %]) + :value @(re-frame/subscribe [::filter :account])}]] [:p.menu-label "Date Range"] [:div [date-range-filter