diff --git a/src/clj/auto_ap/datomic/checks.clj b/src/clj/auto_ap/datomic/checks.clj index abd02576..4afa7391 100644 --- a/src/clj/auto_ap/datomic/checks.clj +++ b/src/clj/auto_ap/datomic/checks.clj @@ -12,6 +12,10 @@ (update :payment/date c/from-date) (update :payment/status :db/ident) (update :payment/type :db/ident) + (update :transaction/_payment (fn [transactions] + (mapv (fn [transaction] + (update transaction :transaction/date c/from-date)) + transactions))) (rename-keys {:invoice-payment/_payment :payment/invoices}))) (def default-read '[* @@ -21,7 +25,8 @@ {:payment/vendor [:vendor/name {:vendor/default-account [:account/name :account/numeric-code :db/id]} :db/id {:vendor/primary-contact [*]} {:vendor/address [*]}]} {:payment/status [:db/ident]} - {:payment/type [:db/ident]}]) + {:payment/type [:db/ident]} + {:transaction/_payment [:db/id :transaction/date]}]) (defn raw-graphql-ids [db args] (let [check-number-like (try (Long/parseLong (:check-number-like args)) (catch Exception e nil)) diff --git a/src/clj/auto_ap/datomic/transactions.clj b/src/clj/auto_ap/datomic/transactions.clj index 47f95911..787ab527 100644 --- a/src/clj/auto_ap/datomic/transactions.clj +++ b/src/clj/auto_ap/datomic/transactions.clj @@ -27,6 +27,10 @@ :args [db]} + (:exact-match-id args) + (merge-query {:query {:in ['?e] + :where []} + :args [(:exact-match-id args)]}) (limited-clients (:id args)) (merge-query {:query {:in ['[?xx ...]] @@ -151,6 +155,7 @@ :transaction/forecast-match [:db/id :forecasted-transaction/identifier] :transaction/vendor [:db/id :vendor/name] :transaction/matched-rule [:db/id :transaction-rule/note] + :transaction/payment [:db/id :payment/date] :transaction/accounts [:transaction-account/amount :db/id :transaction-account/location @@ -159,6 +164,7 @@ ids) (map #(update % :transaction/date c/from-date)) (map #(update % :transaction/post-date c/from-date)) + (map #(update-in % [:transaction/payment :payment/date] c/from-date)) (map #(dissoc % :transaction/id)) (group-by :db/id))] (->> ids diff --git a/src/clj/auto_ap/graphql/checks.clj b/src/clj/auto_ap/graphql/checks.clj index 41322ade..d75526d3 100644 --- a/src/clj/auto_ap/graphql/checks.clj +++ b/src/clj/auto_ap/graphql/checks.clj @@ -20,7 +20,9 @@ [clojure.edn :as edn] [clojure.java.io :as io] [clojure.string :as str] - [config.core :refer [env]]) + [config.core :refer [env]] + [clojure.tools.logging :as log] + [clojure.set :as set]) (:import java.io.ByteArrayOutputStream java.text.DecimalFormat java.util.UUID)) @@ -341,7 +343,15 @@ (defn get-payment-page [context args value] (let [args (assoc args :id (:id context)) [payments checks-count] (d-checks/get-graphql (<-graphql args))] - [{:payments (map ->graphql payments) + + [{:payments (->> payments + (map (fn [payment] + (if (seq (:transaction/_payment payment)) + (-> payment + (set/rename-keys {:transaction/_payment :transaction}) + (update :transaction first)) + payment))) + (map ->graphql )) :total checks-count :count (count payments) :start (:start args 0) diff --git a/src/clj/auto_ap/graphql/invoices.clj b/src/clj/auto_ap/graphql/invoices.clj index e96adf9e..0ea08efa 100644 --- a/src/clj/auto_ap/graphql/invoices.clj +++ b/src/clj/auto_ap/graphql/invoices.clj @@ -18,7 +18,11 @@ (defn get-invoice-page [context args value] (let [args (assoc args :id (:id context)) - [invoices invoice-count outstanding] (d-invoices/get-graphql (update (<-graphql (assoc args :id (:id context))) :status enum->keyword "invoice-status"))] + [invoices invoice-count outstanding] (-> args + (assoc :id (:id context)) + (<-graphql ) + (update :status enum->keyword "invoice-status") + (d-invoices/get-graphql ))] [{:invoices (map ->graphql invoices) :outstanding outstanding :total invoice-count diff --git a/src/cljs/auto_ap/views/components/buttons.cljs b/src/cljs/auto_ap/views/components/buttons.cljs index c736a9c5..96f05a50 100644 --- a/src/cljs/auto_ap/views/components/buttons.cljs +++ b/src/cljs/auto_ap/views/components/buttons.cljs @@ -2,18 +2,22 @@ (:require [auto-ap.views.utils :refer [dispatch-event]] [reagent.core :as r])) -(defn fa-icon [{:keys [event icon class]}] - [:a.button {:class class - :on-click (dispatch-event event)} (into - [:<> - [:span.icon [:i.fa {:class icon}]] - ] - (r/children (r/current-component)))]) +(defn fa-icon [{:keys [event icon class on-click] :as params}] + [:a.button (cond-> params + true (dissoc :event :icon) + (and (not on-click) + event) + (assoc :on-click (dispatch-event event))) + (into + [:<> + [:span.icon [:i.fa {:class icon}]]] + (r/children (r/current-component)))]) -(defn sl-icon [{:keys [event icon class] :as params}] - [:a.button (-> params - (dissoc :event :icon) - (assoc :on-click (dispatch-event event))) +(defn sl-icon [{:keys [event icon class on-click] :as params}] + [:a.button (cond-> params + true (dissoc :event :icon) + (and (not on-click) + event) (assoc :on-click (dispatch-event event))) [:span.icon [:span {:class icon :style {:font-weight "400"}}]]]) (defn new-button [{:keys [event name class ]}] diff --git a/src/cljs/auto_ap/views/components/invoice_table.cljs b/src/cljs/auto_ap/views/components/invoice_table.cljs index b99778a7..15bb71f2 100644 --- a/src/cljs/auto_ap/views/components/invoice_table.cljs +++ b/src/cljs/auto_ap/views/components/invoice_table.cljs @@ -9,7 +9,7 @@ [auto-ap.views.components.grid :as grid] [auto-ap.views.pages.invoices.form :as form] [auto-ap.views.pages.invoices.common :refer [invoice-read]] - [auto-ap.views.utils :refer [date->str dispatch-event nf days-until]] + [auto-ap.views.utils :refer [date->str dispatch-event dispatch-event-with-propagation nf days-until]] [bidi.bidi :as bidi] [cemerick.url :as url] [cljs-time.core :as t] @@ -126,6 +126,7 @@ [:div.buttons (when (seq expense-accounts) [drop-down {:id [::expense-accounts id ] + :is-right? true :header [buttons/sl-icon {:class "badge" :event [::events/toggle-menu [::expense-accounts id]] :data-badge (str (clojure.core/count expense-accounts)) @@ -146,33 +147,32 @@ (when (seq payments) [:<> [drop-down {:id [::payments id] - :header [buttons/sl-icon {:class "badge" - :event [::events/toggle-menu [::payments id]] + :is-right? true + :header [buttons/fa-icon {:class "badge" + :on-click (dispatch-event-with-propagation [::events/toggle-menu [::payments id]]) :data-badge (str (clojure.core/count payments)) - :icon "icon-accounting-bill"}]} - [:div - (for [payment payments] - ^{:key (:id payment)} - [:a.dropdown-item {:href (str (bidi/path-for routes/routes :payments ) - "?" - (url/map->query {:exact-match-id (:id (:payment payment))})) - :target "_new"} - [:i.fa.fa-money-check] - [:span.icon {:class [(when (= :cleared (:status (:payment payment))) - "has-text-success")]} - [:i.fa.fa-money]] - - (if (:check-number (:payment payment)) - (str "Check " (:check-number (:payment payment)) - " (" (gstring/format "$%.2f" (:amount payment) ) ")" - (when (= :cleared (:status (:payment payment))) - (str " - " (:post-date (:transaction (:payment payment)))))) - - (str "Debit (" (gstring/format "$%.2f" (:amount payment) ) ") " - (when (= :cleared (:status (:payment payment))) - (str " - " (:post-date (:transaction (:payment payment))))) - (when (= :cleared (:status (:payment payment))) - (str " - " (:post-date (:transaction (:payment payment))))))) ])]] + :icon "fa-paperclip"}]} + [drop-down-contents + [:div.dropdown-item + [:table.table.grid.compact + [:tbody + (for [invoice-payment payments] + ^{:key (:id invoice-payment)} + [:tr + [:td + "Payment" + ] + [:td (gstring/format "$%.2f" (:amount invoice-payment) )] + [:td + (when (= :cleared (:status (:payment invoice-payment))) + (str "cleared") + )] + [:td (:post-date (:transaction (:payment invoice-payment)))] + [:td + [buttons/fa-icon {:icon "fa-external-link" + :href (str (bidi/path-for routes/routes :payments ) + "?" + (url/map->query {:exact-match-id (:id (:payment invoice-payment))}))}]]])]]]]] [:span {:style {:margin-right "1em"}}]]) (when (and (get actions :edit) (not= ":voided" (:status i))) diff --git a/src/cljs/auto_ap/views/pages/payments.cljs b/src/cljs/auto_ap/views/pages/payments.cljs index b63a2120..6e8be9af 100644 --- a/src/cljs/auto_ap/views/pages/payments.cljs +++ b/src/cljs/auto_ap/views/pages/payments.cljs @@ -47,7 +47,9 @@ [[:payments [:id :status :amount :type :check_number :s3_url [:bank-account [:name]] :date [:vendor [:name :id]] [:client [:name :id]] - [:invoices [:invoice-id [:invoice [:invoice-number :id]]]]]] + [:invoices [:invoice-id [:invoice [:invoice-number :id]] + :amount]] + [:transaction [:id :date]]]] :total :start :end]]]} diff --git a/src/cljs/auto_ap/views/pages/payments/table.cljs b/src/cljs/auto_ap/views/pages/payments/table.cljs index 47b3eb7b..61d98ee9 100644 --- a/src/cljs/auto_ap/views/pages/payments/table.cljs +++ b/src/cljs/auto_ap/views/pages/payments/table.cljs @@ -1,22 +1,21 @@ (ns auto-ap.views.pages.payments.table - (:require [auto-ap.subs :as subs] + (:require [auto-ap.events :as events] [auto-ap.routes :as routes] - [cemerick.url :as url] - [bidi.bidi :as bidi] - [auto-ap.views.components.paginator :refer [paginator]] - [auto-ap.views.components.sorter :refer [sorted-column]] - [auto-ap.views.components.sort-by-list :refer [sort-by-list]] - [auto-ap.views.utils :refer [date->str dispatch-event nf]] - - [auto-ap.views.components.dropdown :refer [drop-down drop-down-contents]] - [auto-ap.events :as events] - [goog.string :as gstring] - [re-frame.core :as re-frame] - [auto-ap.views.components.grid :as grid] - [auto-ap.views.components.buttons :as buttons] [auto-ap.status :as status] - [auto-ap.views.pages.data-page :as data-page])) - + [auto-ap.subs :as subs] + [auto-ap.views.components.buttons :as buttons] + [auto-ap.views.components.dropdown + :refer + [drop-down drop-down-contents]] + [auto-ap.views.components.grid :as grid] + [auto-ap.views.pages.data-page :as data-page] + [auto-ap.views.utils + :refer + [date->str dispatch-event-with-propagation nf pretty]] + [bidi.bidi :as bidi] + [cemerick.url :as url] + [goog.string :as gstring] + [re-frame.core :as re-frame])) (re-frame/reg-event-fx ::void-check @@ -42,7 +41,7 @@ selected-client :selected-client states :states }] - (let [{:keys [client s3-url bank-account payments type check-number date amount id vendor status invoices] :as check} check] + (let [{:keys [client s3-url bank-account payments type check-number date amount id vendor status invoices transaction] :as check} check] [grid/row {:class (:class check) :id id} (when-not selected-client [grid/cell {} (:name client)]) @@ -61,24 +60,39 @@ [grid/button-cell {} [:div.buttons (when (and (seq invoices) (not= :voided status)) - [drop-down {:id [::invoices id] - :header [:button.button.badge {:data-badge (str (clojure.core/count invoices)) - :aria-haspopup true? - :tab-index "0" - :on-click (dispatch-event [::events/toggle-menu [::invoices id]]) - } "Invoices"]} - [:div {:style {:max-width "250px" - :text-overflow "ellipsis" - :white-space "nowrap" - - :overflow "hidden"}} - (for [invoice invoices] - ^{:key (:invoice-number (:invoice invoice))} - [:a.dropdown-item {:href (str (bidi/path-for routes/routes :invoices ) - "?" - (url/map->query {:exact-match-id (:id (:invoice invoice))})) - :target "_new"} - (str " " (:invoice-number (:invoice invoice)))])]]) + [drop-down {:id [::links id] + :is-right? true + :header [buttons/fa-icon {:class "badge" + :on-click (dispatch-event-with-propagation [::events/toggle-menu [::links id]]) + :data-badge (str (cond-> (clojure.core/count invoices) + transaction inc)) + :icon "fa-paperclip"}]} + [drop-down-contents + [:div.dropdown-item + [:table.table.grid.compact + [:tbody + (for [invoice invoices] + ^{:key (:id invoice)} + [:tr + [:td + "Invoice " (:invoice-number (:invoice invoice)) + ] + [:td (gstring/format "$%.2f" (:amount invoice) )] + [:td + [buttons/fa-icon {:icon "fa-external-link" + :href (str (bidi/path-for routes/routes :invoices ) + "?" + (url/map->query {:exact-match-id (:id (:invoice invoice))}))}]]]) + (when transaction + [:tr + [:td + "Transaction"] + [:td (date->str (:date transaction) pretty)] + [:td + [buttons/fa-icon {:icon "fa-external-link" + :href (str (bidi/path-for routes/routes :transactions ) + "?" + (url/map->query {:exact-match-id (:id transaction)}))}]]])]]]]]) [:span {:style {:margin-left "1em"}}] (when (or (= :pending status) diff --git a/src/cljs/auto_ap/views/pages/transactions.cljs b/src/cljs/auto_ap/views/pages/transactions.cljs index 08011a28..582e8948 100644 --- a/src/cljs/auto_ap/views/pages/transactions.cljs +++ b/src/cljs/auto_ap/views/pages/transactions.cljs @@ -31,6 +31,7 @@ :account-id (:id (:account params)) :bank-account-id (:id (:bank-account params)) :amount-gte (:amount-gte (:amount-range params)) + :exact-match-id (some-> (:exact-match-id params) str) :unresolved (:unresolved params) :location (:location params) :amount-lte (:amount-lte (:amount-range params)) diff --git a/src/cljs/auto_ap/views/pages/transactions/common.cljs b/src/cljs/auto_ap/views/pages/transactions/common.cljs index 19a4cb11..66f70217 100644 --- a/src/cljs/auto_ap/views/pages/transactions/common.cljs +++ b/src/cljs/auto_ap/views/pages/transactions/common.cljs @@ -14,6 +14,6 @@ [:forecast-match [:id :identifier]] :status :description_original - [:payment [:check_number :s3_url :id]] + [:payment [:check_number :s3_url :id :date]] [:client [:name :id]] [:bank-account [:name :yodlee-account-id]]]) diff --git a/src/cljs/auto_ap/views/pages/transactions/side_bar.cljs b/src/cljs/auto_ap/views/pages/transactions/side_bar.cljs index 33fb453a..4167307b 100644 --- a/src/cljs/auto_ap/views/pages/transactions/side_bar.cljs +++ b/src/cljs/auto_ap/views/pages/transactions/side_bar.cljs @@ -1,15 +1,17 @@ (ns auto-ap.views.pages.transactions.side-bar (:require [auto-ap.routes :as routes] [auto-ap.subs :as subs] - [auto-ap.views.utils :refer [active-when dispatch-value-change]] + [auto-ap.views.components.bank-account-filter + :refer + [bank-account-filter]] [auto-ap.views.components.date-range-filter :refer [date-range-filter]] [auto-ap.views.components.number-filter :refer [number-filter]] - [auto-ap.views.components.bank-account-filter :refer [bank-account-filter]] [auto-ap.views.components.switch-field :refer [switch-field]] [auto-ap.views.components.typeahead :refer [typeahead-entity]] + [auto-ap.views.pages.data-page :as data-page] + [auto-ap.views.utils :refer [active-when dispatch-event dispatch-value-change]] [bidi.bidi :as bidi] - [re-frame.core :as re-frame] - [auto-ap.views.pages.data-page :as data-page])) + [re-frame.core :as re-frame])) (defn side-bar [{:keys [data-page]}] (let [ap @(re-frame/subscribe [::subs/active-page]) @@ -103,6 +105,12 @@ [:div.control [:input.input {:placeholder "CHECK 123 ABC" :value @(re-frame/subscribe [::data-page/filter data-page :description]) :on-change (dispatch-value-change [::data-page/filter-changed data-page :description])} ]]]] + (when-let [exact-match-id @(re-frame/subscribe [::data-page/filter data-page :exact-match-id])] + [:div + [:p.menu-label "Specific Payment"] + [:span.tag.is-medium exact-match-id " " + [:button.delete.is-small {:on-click + (dispatch-event [::data-page/filter-changed data-page :exact-match-id nil])}]]]) (when (= "admin" (:user/role user)) [:<> diff --git a/src/cljs/auto_ap/views/pages/transactions/table.cljs b/src/cljs/auto_ap/views/pages/transactions/table.cljs index 0cf80298..79af4884 100644 --- a/src/cljs/auto_ap/views/pages/transactions/table.cljs +++ b/src/cljs/auto_ap/views/pages/transactions/table.cljs @@ -8,7 +8,7 @@ [auto-ap.views.pages.transactions.form :as edit] [auto-ap.views.utils :refer - [action-cell-width date->str dispatch-event nf]] + [action-cell-width date->str dispatch-event dispatch-event-with-propagation nf pretty]] [goog.string :as gstring] [re-frame.core :as re-frame] [auto-ap.views.components.buttons :as buttons] @@ -114,24 +114,22 @@ :class (status/class-for (get states id)) :icon "fa-pencil"}] (when payment - [:a.button {:href (str (bidi/path-for routes/routes :payments ) - "?" - (url/map->query {:exact-match-id (:id payment)}))} - - [:span.icon - [:i.fa.fa-money]] - - #_(if (:check-number (:payment payment)) - (str "Check " (:check-number (:payment payment)) - " (" (gstring/format "$%.2f" (:amount payment) ) ")" - (when (= :cleared (:status (:payment payment))) - (str " - " (:post-date (:transaction (:payment payment)))))) - - (str "Debit (" (gstring/format "$%.2f" (:amount payment) ) ") " - (when (= :cleared (:status (:payment payment))) - (str " - " (:post-date (:transaction (:payment payment))))) - (when (= :cleared (:status (:payment payment))) - (str " - " (:post-date (:transaction (:payment payment))))))) ] - #_[:a.tag {:href (:s3-url payment) :target "_new"} - [:span.icon [:i.fa.fa-money]] - (str " " (:check-number payment) " (" (gstring/format "$%.2f" amount ) ")")])]]])]]])) + [drop-down {:id [::links id] + :is-right? true + :header [buttons/fa-icon {:class "badge" + :on-click (dispatch-event-with-propagation [::events/toggle-menu [::links id]]) + :data-badge (str 1) + :icon "fa-paperclip"}]} + [drop-down-contents + [:div.dropdown-item + [:table.table.grid.compact + [:tbody + [:tr + [:td + "Payment"] + [:td (date->str (:date payment) pretty)] + [:td + [buttons/fa-icon {:icon "fa-external-link" + :href (str (bidi/path-for routes/routes :payments ) + "?" + (url/map->query {:exact-match-id (:id payment)}))}]]]]]]]])]]])]]])) diff --git a/src/cljs/auto_ap/views/utils.cljs b/src/cljs/auto_ap/views/utils.cljs index 1daa905f..8c9f5e5f 100644 --- a/src/cljs/auto_ap/views/utils.cljs +++ b/src/cljs/auto_ap/views/utils.cljs @@ -71,6 +71,10 @@ (.preventDefault e)) (re-frame/dispatch-sync event))) +(defn dispatch-event-with-propagation [event] + (fn [e] + (re-frame/dispatch-sync event))) + (def pretty-long (format/formatter "MM/dd/yyyy HH:mm:ss")) (def pretty (format/formatter "MM/dd/yyyy")) (def standard (format/formatter "yyyy-MM-dd"))