more standardization

This commit is contained in:
Bryce Covert
2020-08-17 10:58:05 -07:00
parent 85a110d878
commit 8036d34a4e
12 changed files with 252 additions and 255 deletions

View File

@@ -1,51 +1,28 @@
(ns auto-ap.views.components.expense-accounts-dialog
(:require [auto-ap.entities.invoices-expense-accounts
:as
invoices-expense-accounts]
[auto-ap.events :as events]
(:require [auto-ap.forms :as forms]
[auto-ap.status :as status]
[auto-ap.subs :as subs]
[auto-ap.views.components.modal :refer [action-modal]]
[auto-ap.views.components.typeahead :refer [typeahead]]
[auto-ap.views.utils :refer [bind-field dispatch-event]]
[clojure.spec.alpha :as s]
[auto-ap.utils :refer [by]]
[auto-ap.views.components.modal :as modal]
[auto-ap.views.components.typeahead :refer [typeahead-entity]]
[auto-ap.views.pages.invoices.common :refer [invoice-read]]
[auto-ap.views.utils :refer [dispatch-event with-user]]
[clojure.string :as str]
[goog.string :as gstring]
[re-frame.core :as re-frame]))
(re-frame/reg-sub
::change-expense-accounts
::can-submit
(fn [db]
(-> db ::change-expense-accounts)))
(re-frame/reg-sub
::expense-account
:<- [::change-expense-accounts]
(fn [{{:keys [expense-accounts] :or {expense-accounts [] }} :invoice} [_ invoice-expense-account-id]]
(first (filter #(= invoice-expense-account-id (:id %)) expense-accounts))))
true))
(re-frame/reg-event-fx
::change-expense-accounts
(fn [{:keys [db]} [_ i]]
{:dispatch [::events/modal-status ::change-expense-accounts {:visible? true}]
:db (assoc-in db [::change-expense-accounts :invoice] i)}))
(re-frame/reg-event-db
::change
(fn [db [_ id f v]]
(update-in db [::change-expense-accounts :invoice :expense-accounts]
(fn [expense-accounts]
(mapv
(fn [expense-account]
(if (= id (:id expense-account))
(assoc-in expense-account f v)
expense-account))
expense-accounts)))))
(re-frame/reg-event-fx
::change-expense-accounts-saving
(fn [{:keys [db]} [_ on-success id ]]
(let [{{:keys [expense-accounts total]} :invoice} @(re-frame/subscribe [::change-expense-accounts])
::try-save
[(forms/in-form ::form)]
(fn [{:keys [db]} [_ id ]]
(let [{{:keys [ total]} :invoice
:keys [expense-accounts]} (:data db)
expense-accounts (vals expense-accounts)
expense-accounts-total (->> expense-accounts
(map :new-amount)
(map js/parseFloat)
@@ -56,65 +33,71 @@
(reduce + 0))
does-add-up? (< (Math/abs (- expense-accounts-total (js/parseFloat total))) 0.001)]
(if (and does-add-up?
(every? :new-amount expense-accounts)
(s/valid? (s/* ::invoices-expense-accounts/invoices-expense-account) expense-accounts))
(every? :new-amount expense-accounts))
{:dispatch [::change-expense-accounts-submit on-success id]}
{:dispatch [::events/modal-status ::change-expense-accounts {:saving? false :error-message "Expense accounts do not add up."}]}))))
{:dispatch [::save]}
{:dispatch [::status/error ::form [{:message "Expense accounts do not add up."}]]}))))
(re-frame/reg-event-db
::saving-error
(fn [db [_ message]]
(assoc-in db [::change-expense-accounts :error] message)))
(re-frame/reg-event-fx
::change-expense-accounts-submit
(fn [{:keys [db] } [_ on-success id]]
(let [{:keys [id expense-accounts]} (get-in db [::change-expense-accounts :invoice])]
::save
[with-user (forms/in-form ::form)]
(fn [{:keys [db user] } [_ id]]
(let [{{:keys [id]} :invoice
:keys [expense-accounts]} (:data db)
expense-accounts (vals expense-accounts)]
{:graphql
{:token (-> db :user)
{:token user
:owns-state {:single ::form}
:query-obj {:venia/operation {:operation/type :mutation
:operation/name "EditExpenseAccounts"}
:venia/queries [{:query/data [:edit-expense-accounts
{:invoice-id id
:expense-accounts (map (fn [ea] {:id (if (clojure.string/includes? (:id ea) "new-")
:expense-accounts (map (fn [ea] {:id (if (clojure.string/includes? (str (:id ea)) "new-")
nil
(:id ea)
)
(:id ea))
:amount (:new-amount ea)
:location (:location ea)
:account-id (:id (:account ea))})
expense-accounts)}
[:id :total :outstanding-balance :invoice-number :date :status
[:vendor [:name :id]]
[:expense_accounts [:amount :id :location
[:account [:id :name :numeric-code :location]]]]
[:client [:name :id :locations]]
[:payments [:amount :id [:payment [:amount :s3_url :check_number ]]]]]]}]}
:on-success on-success}})))
invoice-read]}]}
:on-success (fn [result]
[::updated (:edit-expense-accounts result)])}})))
(re-frame/reg-event-fx
::updated
(fn [_ _]
{:dispatch [::modal/modal-closed]}))
(re-frame/reg-event-db
::add-expense-account-split
::add-split
[(forms/in-form ::form)]
(fn [db _]
(let [{{{:keys [locations]} :client} :invoice} @(re-frame/subscribe [::change-expense-accounts])]
(update-in db [::change-expense-accounts :invoice :expense-accounts]
conj {:amount "0.0" :id (str "new-" (random-uuid)) :account {} :location (first locations)}))))
(update-in db [:data :expense-accounts]
assoc (str "new-" (random-uuid)) {:amount "0.0" :account nil :location (-> db :data :invoice :client :locations first) })))
(re-frame/reg-event-db
::remove-expense-account-split
[(forms/in-form ::form)]
(fn [db [_ x]]
(update-in db [::change-expense-accounts :invoice :expense-accounts]
(fn [expense-accounts]
(vec (filter #(not= x (:id %)) expense-accounts) )))))
(update-in db [:data :expense-accounts] dissoc x)))
(def change-expense-accounts-form (forms/vertical-form {:submit-event [::try-save]
:change-event [::forms/change ::form]
:can-submit [::can-submit]
:id ::form}))
(defn change-expense-accounts-modal [{:keys [updated-event]}]
(let [{{:keys [expense-accounts total] :or {expense-accounts [] total 0} {:keys [locations]} :client} :invoice error :error :as data} @(re-frame/subscribe [::change-expense-accounts])
(defn form []
(let [{:keys [data active? error id]} @(re-frame/subscribe [::forms/form ::form])
expense-accounts (:expense-accounts data)
{:keys [total] :or {total 0} {:keys [locations] :as client} :client} (:invoice data)
{:keys [form-inline horizontal-field field raw-field error-notification submit-button]} change-expense-accounts-form
multi-location? (> (count locations) 1)
change-event [::change]
chooseable-expense-accounts @(re-frame/subscribe [::subs/accounts (:client (:invoice data))])
chooseable-expense-accounts @(re-frame/subscribe [::subs/accounts client])
expense-accounts-total (->> expense-accounts
vals
(map :new-amount)
(map js/parseFloat)
(map #(or % 0.0))
@@ -122,85 +105,91 @@
0.0
%))
(reduce + 0))]
[action-modal {:id ::change-expense-accounts
:title "Change expense accounts"
:action-text "Save"
:save-event [::change-expense-accounts-saving updated-event]
:can-submit? true}
(when error
[:div error] )
[:div
[:div
[:a.button.is-primary {:on-click (dispatch-event [::add-expense-account-split])} "Add split"]]
[:table.table
[:thead
[:tr
[:th {:style {:width "500px"}} "Expense Account"]
(when multi-location?
[:th {:style {:width "200px"}} "Location"])
[:th {:style {:width "200px"}} "Original Amount"]
[:th {:style {:width "300px"}} "Amount"]
[:th {:style {:width "5em"}}]]]
[:tbody
(doall (for [{:keys [id] :as expense-account} expense-accounts
:let [sub @(re-frame/subscribe [::expense-account (:id expense-account)])]]
^{:key id}
[:tr
[:td.expandable [:div.control
[bind-field
[typeahead {:matches (map (fn [x] [(:id x) (str (:numeric-code x) " - " (:name x))]) chooseable-expense-accounts)
:type "typeahead"
:field [:account :id]
:event [::change id]
:spec ::invoices-expense-accounts/account-id
:subscription sub}]]]]
[:a.button.is-primary {:on-click (dispatch-event [::add-split])} "Add split"]]
(form-inline {}
[:table.table
[:thead
[:tr
[:th {:style {:width "500px"}} "Expense Account"]
(when multi-location?
[:th {:style {:width "200px"}} "Location"])
[:th {:style {:width "200px"}} "Original Amount"]
[:th {:style {:width "300px"}} "Amount"]
[:th {:style {:width "5em"}}]]]
[:tbody
(doall (for [[id expense-account] expense-accounts]
^{:key id}
[:tr
[:td.expandable [:div.control
(raw-field
[typeahead-entity {:matches chooseable-expense-accounts
:type "typeahead-entity"
:match->text (fn [x] (str (:numeric-code x) " - " (:name x)))
:field [:expense-accounts id :account]}])]]
(when multi-location?
[:td
(if-let [forced-location (:location @(re-frame/subscribe [::subs/account (:client (:invoice data)) (-> sub :account :id )]))]
[:div.select
[:select {:disabled "disabled" :value forced-location} [:option {:value forced-location} forced-location]]]
[:div.select
[bind-field
[:select {:type "select"
:field [:location]
:spec (set locations)
:event [::change id]
:subscription sub}
(map (fn [l] ^{:key l} [:option {:value l} l]) locations)]]])])
[:td
(str "$" (get-in sub [:amount]))]
[:td
[:div.control
[:div.field.has-addons.is-extended
[:p.control [:a.button.is-static "$"]]
[:p.control
[bind-field
[:input.input {:type "number"
:field [:new-amount-temp]
:style {:text-align "right"}
:on-blur (dispatch-event [::change id [:new-amount] (:new-amount-temp sub)])
:on-key-down (fn [e ]
(if (= 13 (.-keyCode e))
(do
(re-frame/dispatch [::change id [:new-amount] (:new-amount-temp sub)])
true)
false))
:event [::change id]
:subscription sub
:value (get-in data [:new-amount-temp])
:max (:total data)
:step "0.01"}]]]]]]
[:td [:a.button {:on-click (dispatch-event [::remove-expense-account-split (:id expense-account)])} [:i.fa.fa-times]]]]))
[:tr
[:td.no-border { :col-span (if multi-location? "3" "2") :style { :text-align "right"} } "Invoice total: "]
[:td.no-border { :style { :text-align "right"} } (str (gstring/format "$%.2f" total ) )]]
[:tr
[:td { :col-span (if multi-location? "3" "2") :style { :text-align "right"} } "Account total: "]
[:td { :style { :text-align "right"} } (str (gstring/format "$%.2f" expense-accounts-total ) )]]
[:tr
[:td.no-border { :col-span (if multi-location? "3" "2") :style { :text-align "right"} } "Difference: "]
[:td.no-border { :style { :text-align "right"} } (str (gstring/format "$%.2f" (- total expense-accounts-total) ) )]]]]]))
(when multi-location?
[:td
(if-let [forced-location (:location @(re-frame/subscribe [::subs/account client (get-in expense-accounts [id :account :id])]))]
[:div.select
[:select {:disabled "disabled" :value forced-location} [:option {:value forced-location} forced-location]]]
[:div.select
(raw-field
[:select {:type "select"
:field [:expense-accounts id :location]
:spec (set locations)}
(map (fn [l] ^{:key l} [:option {:value l} l]) locations)])])])
[:td
(str "$" (get-in expense-accounts [id :amount]))]
[:td
[:div.control
[:div.field.has-addons.is-extended
[:p.control [:a.button.is-static "$"]]
[:p.control
(raw-field
[:input.input {:type "number"
:field [:expense-accounts id :new-amount-temp]
:style {:text-align "right"}
:on-blur (dispatch-event [::forms/change ::form [:expense-accounts id :new-amount] (get-in expense-accounts [id :new-amount-temp])])
:on-key-down (fn [e ]
(if (= 13 (.-keyCode e))
(do
(re-frame/dispatch [::forms/change ::form [:expense-accounts id :new-amount] (get-in expense-accounts [id :new-amount-temp])])
true)
false))
:max (:total data)
:step "0.01"}])]]]]
[:td [:a.button {:on-click (dispatch-event [::remove-expense-account-split id])} [:i.fa.fa-times]]]]))
[:tr
[:td.no-border { :col-span (if multi-location? "3" "2") :style { :text-align "right"} } "Invoice total: "]
[:td.no-border { :style { :text-align "right"} } (str (gstring/format "$%.2f" total ) )]]
[:tr
[:td { :col-span (if multi-location? "3" "2") :style { :text-align "right"} } "Account total: "]
[:td { :style { :text-align "right"} } (str (gstring/format "$%.2f" expense-accounts-total ) )]]
[:tr
[:td.no-border { :col-span (if multi-location? "3" "2") :style { :text-align "right"} } "Difference: "]
[:td.no-border { :style { :text-align "right"} } (str (gstring/format "$%.2f" (- total expense-accounts-total) ) )]]]])]))
(re-frame/reg-event-fx
::show
(fn [{:keys [db]} [_ i]]
(let [accounts-by-id @(re-frame/subscribe [::subs/accounts-by-id])]
{:dispatch [::modal/modal-requested {:title "Change expense accounts"
:body [form]
:confirm {:value "Save"
:status-from [::status/single ::form]
:class "is-primary"
:on-click (dispatch-event [::try-save])
:can-submit [::can-submit]
:close-event [::status/completed ::form]}}]
:db (-> db
(forms/start-form ::form
{:expense-accounts (by :id
(mapv
(fn [ea]
(assoc ea :account (accounts-by-id (:id (:account ea)))))
(:expense-accounts i)))
:invoice i}))})))

View File

@@ -170,7 +170,9 @@
(let [children (r/children (r/current-component))]
[:> Consumer {}
(fn [consume]
(let [{:strs [column-count status]} (js->clj consume)]
(let [{:strs [column-count status check-boxes?]} (js->clj consume)
column-count (cond-> column-count
check-boxes? inc)]
(r/as-element
(cond (= :loading (:state status))
^{:key "loading-body"}

View File

@@ -15,7 +15,8 @@
[cljs-time.core :as t]
[clojure.string :as str]
[goog.string :as gstring]
[re-frame.core :as re-frame]))
[re-frame.core :as re-frame]
[auto-ap.views.components.expense-accounts-dialog :as expense-accounts-dialog]))
(defn query [params]
{:venia/queries [[:invoice_page
@@ -84,15 +85,14 @@
{:invoice-id id}
invoice-read]}]}
:on-success (fn [result]
[::invoice-updated (assoc (:unvoid-invoice result)
:class "live-added")])}}))
[::invoice-updated (:unvoid-invoice result)])}}))
(re-frame/reg-event-fx
::invoice-updated
(fn [{:keys [db]} [_ invoice]]
{:db db}))
(defn row [{:keys [invoice check-boxes checked selected-client overrides expense-event ]}]
(defn row [{:keys [invoice check-boxes checked selected-client overrides expense-event actions]}]
(let [{:keys [client payments expense-accounts invoice-number date due total outstanding-balance id vendor checkable?] :as i} invoice
accounts-by-id @(re-frame/subscribe [::subs/accounts-by-id client])
account->name #(:name (accounts-by-id (:id %)))]
@@ -134,10 +134,12 @@
^{:key (:id e)}
[:span.dropdown-item (account->name (:account e)) " " (gstring/format "$%.2f" (:amount e) ) ])
[:hr.dropdown-divider]
(when (get actions :expense-accounts)
[:<>
(when expense-event
[:a.dropdown-item.is-primary {:on-click (dispatch-event (conj expense-event i))} "Change"])]]])
[:hr.dropdown-divider]
[:a.dropdown-item.is-primary {:on-click (dispatch-event [::expense-accounts-dialog/show i])} "Change"]])]]])
[:span {:style {:margin-left "1em"}}]
(when (seq payments)
[:<>
@@ -165,17 +167,20 @@
(when (= :cleared (:status (:payment payment)))
(str " - " (:post-date (:transaction (:payment payment))))))]))]]
[:span {:style {:margin-right "1em"}}]])
(when (not= ":voided" (:status i))
(when (and (get actions :edit)
(not= ":voided" (:status i)))
[buttons/fa-icon {:icon "fa-pencil"
:event [::form/editing i]}])
(when (and (= (:outstanding-balance i) (:total i)) (not= ":voided" (:status i)))
(when (and (get actions :void)
(= (:outstanding-balance i) (:total i)) (not= ":voided" (:status i)))
[buttons/sl-icon {:icon "icon-bin-2"
:event [::void-invoice i]}])
(when (= ":voided" (:status i))
(when (and (get actions :void)
(= ":voided" (:status i)))
[buttons/fa-icon {:icon "fa-undo"
:event [::unvoid-invoice i]}])]]]))
(defn invoice-table [{:keys [id data checked status vendors check-boxes on-check-changed expense-event overrides]}]
(defn invoice-table [{:keys [id data checked status check-boxes on-check-changed overrides actions]}]
(let [selected-client @(re-frame/subscribe [::subs/client])
{:keys [sort]} @(re-frame/subscribe [::table-params])
selected-client @(re-frame/subscribe [::subs/client])
@@ -204,7 +209,7 @@
:checked checked
:status status
:check-boxes? check-boxes
:column-count (if selected-client 7 8)}
:column-count (if selected-client 8 9)}
[grid/controls data
[:div.level-item
"Outstanding " (nf (:outstanding data))]]
@@ -235,5 +240,5 @@
^{:key id}
[row {:invoice i
:selected-client selected-client
:overrides overrides
:expense-event expense-event}])]])]))
:actions actions
:overrides overrides}])]])]))