good progress on making expense accounts editable.

This commit is contained in:
Bryce Covert
2019-04-17 09:00:34 -07:00
parent b79fca113b
commit b3e407d211
4 changed files with 135 additions and 96 deletions

View File

@@ -50,6 +50,7 @@
(re-frame/reg-event-db
::change
(fn [db [_ form & path-pairs]]
(println "CHANGING" form path-pairs)
(reduce
(fn [db [path value]]
(assoc-in db (into [::forms form :data] path) value))

View File

@@ -0,0 +1,108 @@
(ns auto-ap.views.components.expense-account-field
(:require [auto-ap.forms :as forms]
[auto-ap.subs :as subs]
[auto-ap.views.components.typeahead :refer [typeahead]]
[auto-ap.views.utils :refer [bind-field dispatch-event]]
[goog.string :as gstring]
[re-frame.core :as re-frame]))
;; EVENTS
(re-frame/reg-event-fx
::add-expense-account
(fn [_ [_ event expense-accounts]]
{:dispatch (conj event (conj expense-accounts
{:amount 0 :id (str "new-" (random-uuid))}))}))
(re-frame/reg-event-fx
::remove-expense-account
(fn [_ [_ event expense-accounts id]]
{:dispatch (conj event (transduce (filter
(fn [ea]
(not= (:id ea) id)) )
conj
[]
expense-accounts))}))
(re-frame/reg-event-fx
::expense-account-changed
(fn [_ [_ event expense-accounts field value]]
{:dispatch (into event [(assoc-in expense-accounts field value)
(if (= (list :account :id) (drop 1 field))
(if-let [location (:location @(re-frame/subscribe [::subs/account value]))]
[[(first field) :location] location]))])}))
;; VIEWS
(defn expense-accounts-field [{expense-accounts :value max-value :max locations :locations event :event}]
(let [chooseable-expense-accounts @(re-frame/subscribe [::subs/chooseable-expense-accounts])
accounts-by-id @(re-frame/subscribe [::subs/accounts-for-client-by-id])]
[:div
[:div.columns
[:div.column
[:h1.subtitle.is-4.is-inline "Expense Accounts"]]
[:div.column.is-narrow
[:p.buttons
[:a.button {:on-click (dispatch-event [::add-expense-account event expense-accounts])} "Add"]]]]
(for [[index {:keys [account id location amount] :as expense-account}] (map vector (range) expense-accounts)
:let [account (accounts-by-id (:id account))]]
^{:key id}
[:div.box
[:div.columns
[:div.column
[:h1.subtitle.is-6 (if account
(str (:name account) " - "
location ": "
(gstring/format "$%.2f" (or amount 0) ))
[:i "New expense account"])]]
[:div.column.is-narrow
[:a.button {:on-click (dispatch-event [::remove-expense-account event expense-accounts id])} [:span.icon [:i.fa.fa-times]]]]]
[:div.field
[:div.columns
[:div.column
[:p.help "Expense Account"]
[:div.control.is-fullwidth
[bind-field
[typeahead {:matches (map (fn [x] [(:id x) (str (:numeric-code x) " - " (:name x))]) chooseable-expense-accounts)
:type "typeahead"
:field [index :account :id]
:event [::expense-account-changed event expense-accounts]
:subscription expense-accounts}]]]]
[:div.column.is-narrow
[:p.help "Location"]
[:div.control
(if-let [forced-location (:location account)]
[:div.select
[:select {:disabled "disabled" :style {:width "5em"} :value forced-location} [:option {:value forced-location} forced-location]]]
[:div.select
[bind-field
[:select {:type "select"
:disabled (if (:location account)
"disabled"
"")
:style {:width "5em"}
:field [index :location]
:allow-nil? true
:spec (set locations)
:event [::expense-account-changed event expense-accounts]
:subscription expense-accounts}
(map (fn [l] ^{:key l} [:option {:value l} l]) locations)]]])]]]]
[:div.field
[:p.help "Amount"]
[:div.control
[:div.field.has-addons.is-extended
[:p.control [:a.button.is-static "$"]]
[:p.control
[bind-field
[:input.input {:type "number"
:field [index :amount]
:style {:text-align "right" :width "7em"}
:event [::expense-account-changed event expense-accounts]
:subscription expense-accounts
:value (get-in expense-account [:amount])
:max max-value
:step "0.01"}]]]]]]])]))

View File

@@ -1,11 +1,12 @@
(ns auto-ap.views.pages.invoices.form
(:require [auto-ap.entities.invoice :as invoice]
[auto-ap.utils :refer [by]]
[auto-ap.utils :refer [by dollars=]]
[auto-ap.events :as events]
[auto-ap.forms :as forms]
[auto-ap.subs :as subs]
[auto-ap.views.components.dropdown :refer [drop-down]]
[auto-ap.views.components.typeahead :refer [typeahead]]
[auto-ap.views.components.expense-account-field :refer [expense-accounts-field]]
[auto-ap.views.pages.invoices.common :refer [invoice-read]]
[auto-ap.views.utils
:refer
@@ -21,8 +22,9 @@
(re-frame/reg-sub
::can-submit-edit-invoice
:<- [::form]
:<- [::forms/form ::form]
(fn [{:keys [data status]} _]
(println (s/explain-data ::invoice/invoice data))
(let [min-total (if (= (:total (:original data)) (:outstanding-balance (:original data)))
nil
(- (:total (:original data)) (:outstanding-balance (:original data))))]
@@ -30,7 +32,7 @@
(s/valid? ::invoice/invoice data)
(or (not min-total) (>= (:total data) min-total))
(or (not (:id data))
(< (.abs js/Math (- (js/parseFloat (:total data)) (reduce + 0 (map (fn [ea] (js/parseFloat (:amount ea))) (:expense-accounts data))))) 0.001))))))
(dollars= (js/parseFloat (:total data)) (reduce + 0 (map (fn [ea] (js/parseFloat (:amount ea))) (:expense-accounts data)))))))))
(defmulti submit-query (fn [_ [_ command]]
command))
@@ -134,33 +136,7 @@
[:client-id] value
[:location] first-location]})))
(re-frame/reg-event-fx
::change-expense-account-account
(fn [{:keys [db]} [_ [_ which _] value]]
(let [account @(re-frame/subscribe [::subs/account value])
changes (cond-> [[:expense-accounts which :account :id] value]
(:location account) (into [[:expense-accounts which :location] (:location account)]))]
{:dispatch (into [::forms/change ::form] changes)})))
(re-frame/reg-event-db
::add-expense-account
[(forms/in-form ::form) (re-frame/path [:data])]
(fn [form]
(update form :expense-accounts conj {:amount 0 :id (str "new-" (random-uuid))})))
(re-frame/reg-event-db
::remove-expense-account
[(forms/in-form ::form) (re-frame/path [:data])]
(fn [form [_ x]]
(update form :expense-accounts (fn [eas]
(transduce (filter
(fn [ea]
(not= (:id ea) x)) )
conj
[]
eas)))))
(re-frame/reg-event-fx
::submitted
@@ -199,6 +175,7 @@
;; VIEWS
(defn form [{:keys [can-change-amount?] :as params}]
[forms/side-bar-form {:form ::form }
(let [{:keys [data active? error id]} @(re-frame/subscribe [::forms/form ::form])
@@ -308,74 +285,15 @@
:spec ::invoice/total
:step "0.01"}]]]]]]
[:div
[:div.columns
[:div.column
[:h1.subtitle.is-4.is-inline "Expense Accounts"]]
[:div.column.is-narrow
[:p.buttons
[:a.button {:on-click (dispatch-event [::add-expense-account])} "Add"]]]]
[bind-field
[expense-accounts-field {:subscription data
:type "expense-accounts"
:event change-event
:locations locations
:max-value (:total data)
:field [:expense-accounts]}]]
(for [[index {:keys [account id location amount] :as expense-account}] (map vector (range) (:expense-accounts data))
:let [account (accounts-by-id (:id account))]]
^{:key id}
[:div.box
[:div.columns
[:div.column
[:h1.subtitle.is-6 (if account
(str (:name account) " - "
location ": "
(gstring/format "$%.2f" (or amount 0) ))
[:i "New expense account"])]]
[:div.column.is-narrow
[:a.button {:on-click (dispatch-event [::remove-expense-account id])} [:span.icon [:i.fa.fa-times]]]]]
[:div.field
[:div.columns
[:div.column
[:p.help "Expense Account"]
[:div.control.is-fullwidth
[bind-field
[typeahead {:matches (map (fn [x] [(:id x) (str (:numeric-code x) " - " (:name x))]) chooseable-expense-accounts)
:type "typeahead"
:field [:expense-accounts index :account :id]
:event [::change-expense-account-account]
:subscription data}]]]]
[:div.column.is-narrow
[:p.help "Location"]
[:div.control
(if-let [forced-location (:location account)]
[:div.select
[:select {:disabled "disabled" :style {:width "5em"} :value forced-location} [:option {:value forced-location} forced-location]]]
[:div.select
[bind-field
[:select {:type "select"
:disabled (if (:location account)
"disabled"
"")
:style {:width "5em"}
:field [:expense-accounts index :location]
:allow-nil? true
:spec (set locations)
:event [::forms/change ::form]
:subscription data}
(map (fn [l] ^{:key l} [:option {:value l} l]) locations)]]])]]]]
[:div.field
[:p.help "Amount"]
[:div.control
[:div.field.has-addons.is-extended
[:p.control [:a.button.is-static "$"]]
[:p.control
[bind-field
[:input.input {:type "number"
:field [:expense-accounts index :amount]
:style {:text-align "right" :width "7em"}
:event [::forms/change ::form]
:subscription data
:value (get-in expense-account [:amount])
:max (:total data)
:step "0.01"}]]]]]]])]
(when error
^{:key error} [:div.notification.is-warning.animated.fadeInUp

View File

@@ -140,6 +140,18 @@
keys (dissoc keys :field :subscription :event :spec)]
(into [dom keys] (with-keys rest))))
(defmethod do-bind "expense-accounts" [dom {:keys [field event subscription class spec] :as keys} & rest]
(let [field (if (keyword? field) [field] field)
event (if (keyword? event) [event] event)
keys (assoc keys
:value (get-in subscription field)
:event (conj event field)
:class (str class
(when (and spec (not (s/valid? spec (get-in subscription field))))
" is-danger")))
keys (dissoc keys :field :subscription :spec)]
(into [dom keys] (with-keys rest))))
(defmethod do-bind :default [dom {:keys [field event subscription class spec] :as keys} & rest]
(let [field (if (keyword? field) [field] field)
event (if (keyword? event) [event] event)