removed redundant stuff.

This commit is contained in:
2022-07-22 22:55:26 -07:00
parent 7f5a2ea353
commit 005bfe2603
21 changed files with 357 additions and 399 deletions

View File

@@ -247,6 +247,7 @@
:transaction/bank-account [:bank-account/name :bank-account/code :bank-account/yodlee-account-id :db/id :bank-account/locations :bank-account/current-balance]
:transaction/vendor [:db/id :vendor/name]
:transaction/matched-rule [:db/id :transaction-rule/note]
:transaction/forecast-match [:db/id :forecasted-transaction/identifier]
:transaction/accounts [:transaction-account/amount
:db/id
:transaction-account/location

View File

@@ -100,12 +100,6 @@
(re-frame/reg-event-db
::check-problems
(fn [db [_ form schema]]
(println "Checking problems"
form
(get-in db [::forms form :data])
(keys (get-in db [::forms]))
schema
(m/explain schema (get-in db [::forms form :data])))
(assoc-in db [::forms form :problems]
(when schema (m/explain schema (get-in db [::forms form :data]))))))

View File

@@ -89,11 +89,13 @@
(into [:fieldset {:disabled (boolean (= :loading (:state status)))}]
(r/children (r/current-component)))]
))))
;; TODO make virtual builder operate as a cursor and an input instead of a whole new thing
;; make it inherit the outer form, avoiding creating new forms
(defn virtual-builder []
(let [starting-key (random-uuid)
key (r/atom starting-key)]
(fn [{:keys [value on-change can-submit error-messages fullwidth? schema]}]
(re-frame/dispatch [::forms/start-form starting-key []])
(fn [{:keys [value on-change can-submit error-messages fullwidth? schema attempted-submit?]}]
(let [data-sub [::forms/form @key]
{:keys [data error problems visited]} @(re-frame/subscribe data-sub)
data (or value data)]
@@ -101,11 +103,12 @@
:error-messages (or error-messages
nil)
;; wrap to make sure raw form updates too
:on-change (fn [v]
:on-change (fn [v o]
(re-frame/dispatch-sync [::forms/reset @key v])
(on-change v))
(on-change v o))
:blur-event [::blurred schema @key ]
:problems problems
:attempted-submit? attempted-submit?
:visited visited
:error error
:id @key
@@ -206,7 +209,6 @@
nil)
visited? (get visited full-field-path)
value (get-in data full-field-path)]
(println "VISITED " visited full-field-path problems)
(-> child-props
(assoc :on-change
(if on-change
@@ -246,22 +248,6 @@
label)])
(into [:div.control ] children)]))))
(defn field []
(let [props (r/props (r/current-component))
[label child] (r/children (r/current-component))]
[:> Consumer {}
(fn [consume]
(r/as-element
[:div.field
(when label
(if (aget consume "fullwidth?")
[:p.help label]
[:label.label
(if (:required? props)
[:span label [:span.has-text-danger " *"]]
label)]))
[:div.control [raw-field {} child]]]))]))
(defn field-v2 []
(let [props (r/props (r/current-component))
[label child] (r/children (r/current-component))]
@@ -280,23 +266,6 @@
[:div
[raw-error-v2 {:field (:field props)}]]]))))
(defn horizontal-control []
(let [[label & children] (r/children (r/current-component))]
[:div.field.is-horizontal
(when label
[:div.field-label [:label.label label]])
[:div.field-body
(for [[i child] (map vector (range) children)]
^{:key i}
[:div.field
child])]]))
(defn horizontal-field []
(let [[label child] (r/children (r/current-component))]
[horizontal-control
label
[raw-field {} child]]))
(defn section [{:keys [title]}]
[:<>
[:h4.is-4.title title]

View File

@@ -21,3 +21,6 @@
[:account reference]
[:location :string]
[:amount money]]))
(def approval-status (m/schema [:enum :unapproved :requires-feedback :approved :excluded]))

View File

@@ -4,7 +4,8 @@
[auto-ap.views.components.multi :as multi]
[auto-ap.views.components.money-field :as money]
[auto-ap.views.components.number :as number]
[auto-ap.views.components.typeahead.vendor :as typeahead]))
[auto-ap.views.components.typeahead.vendor :as typeahead]
[auto-ap.views.components.button-radio :as br]))
(defn checkbox [{:keys [on-change
@@ -49,6 +50,16 @@
(for [[k v] options]
^{:key k} [:option {:value k} v])]]])
(defn switch-input [{:keys [id label on-change value class]}]
[:<>
[:input.switch {:type "checkbox"
:id id
:on-change (fn []
(on-change (not value)))
:checked (boolean value)
:class class}]
[:label {:for id} label]])
(def multi-field-v2 multi/multi-field-v2)
(def number-input number/number-input)
@@ -58,4 +69,4 @@
(def search-backed-typeahead typeahead/search-backed-typeahead)
(def entity-typeahead typeahead/typeahead-v3)
(def button-radio-input auto-ap.views.components.button-radio/button-radio)
(def button-radio-input br/button-radio)

View File

@@ -240,7 +240,8 @@
:schema schema
:on-change (fn [expense-accounts original-expense-accounts]
(let [updated-expense-accounts
(for [[before-account after-account] (map vector original-expense-accounts expense-accounts)]
(for [[before-account after-account] (map vector (concat original-expense-accounts
(repeat nil)) expense-accounts)]
(cond-> after-account
(not= (:id (:account before-account))
(:id (:account after-account)))

View File

@@ -9,7 +9,8 @@
[auto-ap.forms.builder :as form-builder]))
(defn multi-field-v2-internal [{:keys [template key-fn next-key allow-change? disable-new? disable-remove? schema on-change disabled new-text] prop-value :value :as props} ]
;; TODO just embrace the fact that it will need to be remounted, and use index based keys
(defn multi-field-v2-internal [{:keys [template key-fn allow-change? disable-new? disable-remove? schema on-change disabled new-text] prop-value :value :as props} ]
(let [prop-value (if (seq prop-value)
prop-value
[])]
@@ -18,17 +19,23 @@
:on-change on-change}
[:fieldset {:disabled disabled}
[:div {:style {:margin-bottom "0.25em"}}
(into [appearing-group]
(into [(if key-fn
appearing-group
[:<>])]
(for [[i override] (map vector (range) prop-value)
:let [extant? (boolean (key-fn override))
:let [extant? (if key-fn
(boolean (key-fn override))
true)
is-disabled? (boolean (and (= false allow-change?)
extant?))]]
^{:key (or (key-fn override)
(::key override))}
^{:key (or (when key-fn (key-fn override))
(::key override)
i)}
[form-builder/with-scope {:scope [i]}
^{:key (or (key-fn override)
(::key override))}
^{:key (or (when key-fn (key-fn override))
(::key override)
i)}
[:div.level {:style {:margin-bottom "0.25em"}}
[:div.level-left {:style {:padding "0.5em 1em"}
:class (when-not extant?

View File

@@ -269,7 +269,7 @@
[:vendor {:optional true}
[:maybe schema/reference]]
[:transaction-approval-status {:optional true}
[:maybe [:enum :unapproved :requires-feedback :approved :excluded]]]
[:maybe schema/approval-status]]
[:note {:optional true}
[:maybe :string]]]))

View File

@@ -11,29 +11,6 @@
[malli.core :as m]
[re-frame.core :as re-frame]))
(re-frame/reg-event-fx
::saving
[with-user (forms/in-form ::form)]
(fn [{:keys [db user]} [_]]
{:graphql
{:token user
:owns-state {:single ::form}
:query-obj {:venia/operation {:operation/type :mutation
:operation/name "EditUser"}
:venia/queries [{:query/data [:edit-user
{:edit-user (-> (:data db)
(update :clients #(map (comp :id :client) %))
(select-keys #{:id :name :clients :role}))}
[:id :name :role [:clients [:id :name]]]]}]}
:on-success [::saved]}}))
(re-frame/reg-event-fx
::saved
(forms/triggers-stop ::form)
(fn [_ _]
{:dispatch [::modal/modal-closed]}))
(def client-schema
(m/schema [:map [:client schema/reference]]))
@@ -46,11 +23,40 @@
[:maybe
[:sequential client-schema]]]]))
(re-frame/reg-event-fx
::saving
[with-user (forms/in-form ::form)]
(fn [{:keys [db user]} [_]]
(if (m/validate user-schema (:data db))
{:graphql
{:token user
:owns-state {:single ::form}
:query-obj {:venia/operation {:operation/type :mutation
:operation/name "EditUser"}
:venia/queries [{:query/data [:edit-user
{:edit-user (-> (:data db)
(update :clients #(map (comp :id :client) %))
(select-keys #{:id :name :clients :role}))}
[:id :name :role [:clients [:id :name]]]]}]}
:on-success [::saved]}}
{:dispatch-n [[::forms/attempted-submit ::form]
[::status/error ::form [{:message "Please fix the errors and try again."}]]]})
))
(re-frame/reg-event-fx
::saved
(forms/triggers-stop ::form)
(fn [_ _]
{:dispatch [::modal/modal-closed]}))
(defn form []
(let [{:keys [data]} @(re-frame/subscribe [::forms/form ::form])
clients @(re-frame/subscribe [::subs/clients])]
(println data)
[:<>
[form-builder/builder {:submit-event [::saving]
:id ::form

View File

@@ -1,43 +1,40 @@
(ns auto-ap.views.pages.admin.vendors.merge-dialog
(:require
[auto-ap.forms :as forms]
[auto-ap.forms.builder :as form-builder]
[auto-ap.schema :as schema]
[auto-ap.status :as status]
[auto-ap.subs :as subs]
[auto-ap.views.components :as com]
[auto-ap.views.components.modal :as modal]
[auto-ap.views.components.typeahead.vendor
:refer [search-backed-typeahead]]
[auto-ap.views.utils :refer [dispatch-event]]
[re-frame.core :as re-frame]
[auto-ap.forms.builder :as form-builder]))
[malli.core :as m]
[re-frame.core :as re-frame]))
(re-frame/reg-sub
::can-submit
:<- [::forms/form ::form]
(fn [{:keys [data]}]
(and (:from data)
(:to data))))
(def merge-schema
(m/schema [:map
[:from schema/reference]
[:to schema/reference]]))
(defn form []
[form-builder/builder {:submit-event [::save]
:can-submit [::can-submit]
:id ::form}
[form-builder/field "Form Vendor (will be deleted)"
[search-backed-typeahead {:search-query (fn [i]
[:search_vendor
{:query i}
[:name :id]])
:type "typeahead-v3"
:auto-focus true
:field [:from]}]]
[form-builder/builder {:submit-event [::try-save]
:id ::form
:schema merge-schema}
[form-builder/field-v2 {:field :from}
"Form Vendor (will be deleted)"
[com/search-backed-typeahead {:search-query (fn [i]
[:search_vendor
{:query i}
[:name :id]])
:auto-focus true}]]
[form-builder/field "To Vendor"
[search-backed-typeahead {:search-query (fn [i]
[:search_vendor
{:query i}
[:name :id]])
:type "typeahead-v3"
:field [:to]}]]
[form-builder/field-v2 {:field :to}
"To Vendor"
[com/search-backed-typeahead {:search-query (fn [i]
[:search_vendor
{:query i}
[:name :id]])}]]
[form-builder/hidden-submit-button]])
(re-frame/reg-event-fx
@@ -48,8 +45,7 @@
:confirm {:value "Merge"
:status-from [::status/single ::form]
:class "is-primary"
:on-click (dispatch-event [::save])
:can-submit [::can-submit]
:on-click (dispatch-event [::try-save])
:close-event [::status/completed ::form]}}]
:db (forms/start-form db ::form {})}))
@@ -73,3 +69,12 @@
{:from (:id from) :to (:id to)} []]}]}
:on-success [::complete]}})))
(re-frame/reg-event-fx
::try-save
[(forms/in-form ::form)]
(fn [{:keys [db]}]
(if (not (m/validate merge-schema (:data db)))
{:dispatch-n [[::status/error ::form [{:message "Please correct any errors and try again"}]]
[::forms/attempted-submit ::form]]}
{:dispatch [::save]})))

View File

@@ -2,59 +2,48 @@
(:require
[auto-ap.forms :as forms]
[auto-ap.forms.builder :as form-builder]
[auto-ap.schema :as schema]
[auto-ap.status :as status]
[auto-ap.subs :as subs]
[auto-ap.views.components :as com]
[auto-ap.views.components.modal :as modal]
[auto-ap.views.components.money-field :refer [money-field]]
[auto-ap.views.pages.invoices.common
:refer [does-amount-exceed-outstanding? invoice-read]]
[auto-ap.views.components.money-field :refer [money-field]]
[auto-ap.views.utils :refer [dispatch-event horizontal-field with-user]]
[re-frame.core :as re-frame]
[auto-ap.views.components :as com]
[auto-ap.views.utils :refer [coerce-float dispatch-event with-user]]
[malli.core :as m]
[auto-ap.schema :as schema]))
(re-frame/reg-sub
::can-submit
:<- [::forms/form ::form]
(fn [{ {:keys [invoices invoice-amounts]} :data}]
(cond
(->> invoice-amounts
vals
(map :amount)
(filter nil?)
seq)
false
(seq (filter
(fn [{:keys [id outstanding-balance]}]
(does-amount-exceed-outstanding? (get-in invoice-amounts [id :amount]) outstanding-balance ))
invoices))
false
:else
true)))
[malli.error :as me]
[re-frame.core :as re-frame]))
(def advanced-print-schema (m/schema
[:map
[:bank-account-id schema/not-empty-string]]))
[:and
[:map
[:bank-account-id schema/not-empty-string]
[:invoice-amounts [:map-of
:string
[:map
[:amount schema/money]]]]]
[:fn (fn [{:keys [invoices invoice-amounts] :as z}]
(println "HERE" z)
(when (seq (filter
(fn [{:keys [id outstanding-balance]}]
(does-amount-exceed-outstanding? (get-in invoice-amounts [id :amount]) outstanding-balance ))
invoices))
(throw (ex-info "Invalid" {:type ::too-much-invoice}))))]]))
(defn form []
(let [real-bank-accounts @(re-frame/subscribe [::subs/real-bank-accounts])
{:keys [data]} @(re-frame/subscribe [::forms/form ::form])]
(println "TEST?")
[form-builder/builder {:submit-event [::try-save]
:can-submit [::can-submit]
:id ::form
:schema advanced-print-schema}
[:div.field
[:label.label "Pay using"]
[:div.control
[:span.select
[form-builder/raw-field-v2 {:field :bank-account-id}
[com/select-field {:options (for [{:keys [id name]} real-bank-accounts]
[form-builder/field-v2 {:field :bank-account-id}
"Pay using"
[com/select-field {:options (for [{:keys [id name]} real-bank-accounts]
[id name])
:allow-nil? true}]]]]]
:allow-nil? true}]]
[:table.table.is-fullwidth
[:thead
@@ -64,14 +53,14 @@
[:th {:style {"width" "10em"}} "Payment"]]]
[:tbody
(doall
(for [{:keys [vendor invoice-number id] :as i} (:invoices data)]
(for [{:keys [vendor invoice-number id]} (:invoices data)]
^{:key id}
[:tr
[:td (:name vendor)]
[:td invoice-number]
[:td
[form-builder/raw-field-v2 {:field [:invoice-amounts :id :amount]}
[form-builder/raw-field-v2 {:field [:invoice-amounts id :amount]}
[money-field]]]]))]]]))
(re-frame/reg-event-fx
@@ -83,14 +72,13 @@
: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
{:invoices invoices
:invoice-amounts (into {}
(map (fn [i] [(:id i)
{:amount (:outstanding-balance i)}])
{:amount (coerce-float (:outstanding-balance i))}])
invoices))}))}))
@@ -115,7 +103,7 @@
first
:type)
:check)
{:keys [date invoices invoice-amounts check-number bank-account-id client]} (:data db)]
{:keys [invoices invoice-amounts bank-account-id]} (:data db)]
{:graphql
{:token user
:owns-state {:single ::form}
@@ -139,6 +127,6 @@
(re-frame/reg-event-fx
::checks-printed
(fn [{:keys [db]} [_ data]]
(fn [{:keys [_]} [_ _]]
{:dispatch [::modal/modal-closed]}))

View File

@@ -33,7 +33,8 @@
[reagent.core :as r]
[malli.core :as m]
[vimsical.re-frame.cofx.inject :as inject]
[vimsical.re-frame.fx.track :as track]))
[vimsical.re-frame.fx.track :as track]
[auto-ap.views.components :as com]))
(def schema (m/schema
@@ -392,12 +393,10 @@
[date-picker {:output :cljs-date}]]
[form-builder/raw-error-v2 {:field :scheduled-payment}]]
[:div.control
[form-builder/raw-field
[form-builder/raw-field-v2 {:field :schedule-when-due}
[switch-field {:id "schedule-when-due"
:field [:schedule-when-due]
:label "Same as due date"
:type "checkbox"}]]]]]
[com/switch-input {:id "schedule-when-due"
:label "Same as due date"}]]]]]
[form-builder/field-v2 {:required? true
:field :invoice-number}
"Invoice #"

View File

@@ -11,32 +11,40 @@
[auto-ap.views.utils
:refer [date-picker dispatch-event with-user]]
[clojure.string :as str]
[re-frame.core :as re-frame]))
[re-frame.core :as re-frame]
[auto-ap.views.components :as com]
[malli.core :as m]
[auto-ap.schema :as schema]))
(def handwritten-check-schema
(m/schema
[:map
[:bank-account-id schema/not-empty-string]
[:date schema/date]
[:check-number [:int {:min 1000 :max 99999}]]
]))
(defn form []
(let [real-bank-accounts @(re-frame/subscribe [::subs/real-bank-accounts])
{:keys [data]} @(re-frame/subscribe [::forms/form ::form])]
[form-builder/builder {:submit-event [::save]
:can-submit [::can-submit]
:id ::form}
[form-builder/vertical-control
:id ::form
:schema handwritten-check-schema}
[form-builder/field-v2 {:field :bank-account-id}
"Pay using"
[:div.control
[:span.select
[form-builder/raw-field
[:select {:type "select"
:field :bank-account-id}
(for [{:keys [id name]} real-bank-accounts]
^{:key id} [:option {:value id} name])]]]]]
[form-builder/field
[com/select-field {:options (for [{:keys [id name]} real-bank-accounts]
[id name])
:allow-nil? true}]]
[form-builder/field-v2 {:field :date}
"Date"
[date-picker {:type "date"
:output :cljs-date
:field [:date]}]]
[form-builder/field
:output :cljs-date}]]
[form-builder/field-v2 {:field :check-number}
"Check number"
[:input.input {:type "number"
:field [:check-number]}]]
[com/number-input {:style {:width "8em"}}]]
[:table.table.is-fullwidth
[:thead
[:tr
@@ -49,11 +57,8 @@
[:tr
[:td invoice-number]
[:td
[form-builder/raw-field
[money-field {:type "money"
:field [:invoice-amounts id :amount]
:style {:max-width "8em"}
}]]]]))]]
[form-builder/raw-field-v2 {:field [:invoice-amounts id :amount]}
[money-field {:style {:max-width "9em"}}]]]]))]]
[form-builder/hidden-submit-button]]))
(re-frame/reg-sub
@@ -83,7 +88,7 @@
:close-event [::status/completed ::form]}}]
:db (-> db
(forms/start-form ::form
{:bank-account-id (:id (first @(re-frame/subscribe [::subs/real-bank-accounts])))
{:bank-account-id nil
:invoices invoices
:invoice-amounts (into {}
(map (fn [i] [(:id i)

View File

@@ -24,7 +24,8 @@
[vimsical.re-frame.fx.track :as track]
[vimsical.re-frame.cofx.inject :as inject]
[auto-ap.views.pages.ledger.report-table :as rtable]
[auto-ap.forms.builder :as form-builder]))
[auto-ap.forms.builder :as form-builder]
[auto-ap.views.components :as com]))
(defn data-params->query-params [params]
(when params
@@ -190,26 +191,20 @@ NOTE: Please review the transactions we may have question for you here: https://
[:div.level-left
[:div.level-item
[:div.control
[form-builder/field
[form-builder/field-v2 {:field :date}
"Date"
[date-picker {:output :cljs-date
:type "date"
:field [:date]}]]]]
[date-picker {:output :cljs-date}]]]]
[:div.level-item
[form-builder/field
[form-builder/field-v2 {:field :include-comparison}
[:div.mt-5]
[switch-field {:id "include-comparison"
:field [:include-comparison]
:label "Include compariison"
:type "checkbox"}]]]
[com/switch-input {:id "include-comparison"
:label "Include compariison"}]]]
[:div.level-item
(when (boolean (:include-comparison data))
[form-builder/field
[form-builder/field-v2 {:field :comparison-date}
"Comparison Date"
[date-picker {:output :cljs-date
:type "date"
:field [:comparison-date]}]])]]
[date-picker {:output :cljs-date}]])]]
[:div.level-right
[:div.buttons

View File

@@ -32,7 +32,8 @@
[reagent.core :as reagent]
[vimsical.re-frame.cofx.inject :as inject]
[vimsical.re-frame.fx.track :as track]
[auto-ap.forms.builder :as form-builder]))
[auto-ap.forms.builder :as form-builder]
[auto-ap.views.components :as com]))
@@ -73,7 +74,7 @@
(cond-> {:graphql {:token user
:owns-state {:single ::page}
:query-obj {:venia/queries [[:profit-and-loss
{:client-ids (map :id (:clients (:data db)))
{:client-ids (map (comp :id :client) (:clients (:data db)))
:periods (mapv #(select-keys % #{:start :end} ) (:periods (:data db)))
:include-deltas (:include-deltas (:data db))
:column-per-location (:column-per-location (:data db))}
@@ -82,7 +83,7 @@
:set-uri-params {:periods (mapv
encode-period
(:periods (:data db)))
:clients (mapv #(select-keys % [:name :id]) (:clients (:data db))) }
:clients (mapv #(select-keys (:client %) [:name :id]) (:clients (:data db))) }
:db (-> db
(dissoc :report)
(update-in [:data :clients] #(into [] (filter seq %))))})))
@@ -127,14 +128,14 @@ NOTE: Please review the transactions we may have question for you here: https://
(cond-> {:graphql {:token user
:owns-state {:single ::page}
:query-obj {:venia/queries [[:profit-and-loss-pdf
{:client-ids (map :id (:clients (:data db)))
{:client-ids (map (:comp :id :client) (:clients (:data db)))
:include-deltas (:include-deltas (:data db))
:column-per-location (:column-per-location (:data db))
:periods (mapv #(select-keys % #{:start :end}) (:periods (:data db)))}
[:url :name]]]}
:on-success [::received-pdf]}
:set-uri-params {:periods (mapv encode-period (:periods (:data db)))
:clients (mapv #(select-keys % [:name :id]) (:clients (:data db))) }
:clients (mapv #(select-keys (:client %) [:name :id]) (:clients (:data db))) }
:db (dissoc db :report)})))
@@ -228,7 +229,6 @@ NOTE: Please review the transactions we may have question for you here: https://
(defn report-control-detail [{:keys [active box which]} children]
(when (and @box
(= which @active))
(println @box)
(react-dom/createPortal (reagent/as-element
[:div.notification.is-light
[:a.delete {:on-click (fn [] (reset! active nil))}]
@@ -268,17 +268,17 @@ NOTE: Please review the transactions we may have question for you here: https://
[buttons/dropdown {:on-click (fn [] (reset! active :clients))}
[:span (str "Companies"
(when-let [clients (:clients data)]
(str " (" (str/join ", " (map :name clients)) ")")))]]
(str " (" (str/join ", " (map (comp :name :client) clients)) ")")))]]
[report-control-detail {:active active :box !box :which :clients}
[:div {:style {:width "20em"}}
[:h4.subtitle "Companies"]
[form-builder/raw-field
[multi-field {:type "multi-field"
:field [:clients]
:template [[typeahead-v3 {:entities @(re-frame/subscribe [::subs/clients])
:style {:width "18em"}
:entity->text :name
:type "typeahead-v3"}]]}]]]]]
[form-builder/raw-field-v2 {:field :clients}
[com/multi-field-v2 {:new-text "Add another company"
:template [[form-builder/raw-field-v2 {:field :client}
[com/entity-typeahead {:entities @(re-frame/subscribe [::subs/clients])
:style {:width "18em"}
:entity->text :name}]]]
:key-fn :id}]]]]]
[:div.level-item
[buttons/dropdown {:on-click (fn [] (reset! active :range))}
[:span (str "Range"
@@ -291,11 +291,9 @@ NOTE: Please review the transactions we may have question for you here: https://
[:div.control
[:div.field.has-addons
[:div.control
[form-builder/raw-field
[form-builder/raw-field-v2 {:field :thirteen-periods-end}
[date-picker {:placeholder "End date"
:type "date"
:output :cljs-date
:field [:thirteen-periods-end]}]]]
:output :cljs-date}]]]
[period-preset-button {:title "13 periods"
:periods (let [today (or (some-> (:thirteen-periods-end data))
(local-today))]
@@ -312,11 +310,9 @@ NOTE: Please review the transactions we may have question for you here: https://
[:div.control
[:div.field.has-addons
[:div.control
[form-builder/raw-field
[form-builder/raw-field-v2 {:field :twelve-periods-end}
[date-picker {:placeholder "End date"
:output :cljs-date
:type "date"
:field [:twelve-periods-end]}]]]
:output :cljs-date}]]]
[period-preset-button {:title "12 months"
:periods (let [end-date (or (some-> (:twelve-periods-end data))
(local-today))
@@ -378,22 +374,15 @@ NOTE: Please review the transactions we may have question for you here: https://
:end (local-today)})
:title "Full year"}]]
[:div
[:div.field
[:label.checkbox
[form-builder/raw-field
[:input {:type "checkbox"
:field [:show-advanced?]}]]
" Show Advanced"]]]
[form-builder/raw-field-v2 {:field :show-advanced?}
[com/checkbox {:label "Show Advanced"}]
]]
(when (:show-advanced? data)
[form-builder/raw-field
[multi-field {:type "multi-field"
:field [:periods]
:template [[date-picker {:type "date"
:output :cljs-date
:field [:start]}]
[date-picker {:type "date"
:output :cljs-date
:field [:end]}]]}]])]]]
[form-builder/raw-field-v2 {:field :periods}
[com/multi-field-v2 {:template [[form-builder/raw-field-v2 {:field :start}
[date-picker {:output :cljs-date}]]
[form-builder/raw-field-v2 {:field :end}
[date-picker {:output :cljs-date}]]]}]])]]]
[:div.level-item
[:div
@@ -446,7 +435,7 @@ NOTE: Please review the transactions we may have question for you here: https://
report (l-reports/summarize-pnl pnl-data)
table (rtable/concat-tables (concat (:summaries report) (:details report)))]
[:div
[:h1.title "Profit and Loss - " (str/join ", " (map :name (:clients args)))]
[:h1.title "Profit and Loss - " (str/join ", " (map (comp :name :client) (:clients args)))]
(when (:warning report)
[:div.notification.is-warning.is-light
(:warning report)])
@@ -487,8 +476,9 @@ NOTE: Please review the transactions we may have question for you here: https://
(mapv (fn [period]
{:start (str->date (:start period) standard)
:end (str->date (:end period) standard)})))
:clients (or (:clients qp)
[(some-> @(re-frame/subscribe [::subs/client]) (select-keys [:name :id]))])
:clients (mapv (fn [c] {:client c :id (random-uuid)})
(or (:clients qp)
[(some-> @(re-frame/subscribe [::subs/client]) (select-keys [:name :id]) )]))
:include-deltas false})
::track/register {:id ::ledger-params
:subscription [::data-page/params ::ledger]

View File

@@ -4,17 +4,12 @@
[auto-ap.subs :as subs]
[auto-ap.views.components.layouts :as layouts]
[auto-ap.views.components.money-field :refer [money-field]]
[auto-ap.views.components.typeahead :refer [typeahead-v3]]
[auto-ap.views.utils
:refer [date->str date-picker dispatch-event standard]]
[re-frame.core :as re-frame]
[auto-ap.forms.builder :as form-builder]))
[auto-ap.forms.builder :as form-builder]
[auto-ap.views.components :as com]))
(re-frame/reg-sub
::can-submit
:<- [::forms/form ::form]
(fn [{:keys [data status]} _]
false))
(re-frame/reg-event-db
::editing
@@ -26,63 +21,52 @@
(defn form []
[layouts/side-bar {:on-close (dispatch-event [::forms/form-closing ::form ])}
(let [{:keys [data]} @(re-frame/subscribe [::forms/form ::form])]
[form-builder/builder {:can-submit [::can-submit]
:submit-event [::saving ]
[form-builder/builder {:submit-event [::saving ]
:id ::form}
[form-builder/section {:title "Sales Order"}
(when-not @(re-frame/subscribe [::subs/client])
[form-builder/field
[form-builder/field-v2 {:field :client}
"Client"
[typeahead-v3 {:entities @(re-frame/subscribe [::subs/clients])
:entity->text :name
:type "typeahead-v3"
:field [:client]
:disabled true}]])
[com/entity-typeahead {:entities @(re-frame/subscribe [::subs/clients])
:entity->text :name
:disabled true}]])
[form-builder/field "Date"
[date-picker {:type "date"
:output :cljs-date
:disabled true
:field [:date]}]]
[form-builder/field
[form-builder/field-v2 {:field :date}
"Date"
[date-picker {:output :cljs-date
:disabled true}]]
[form-builder/field-v2 {:field :total}
"Total"
[money-field {:type "money"
:field [:total]
:disabled true}]]
[form-builder/field "Tax"
[money-field {:type "money"
:field [:tax]
:disabled true}]
[form-builder/field
[money-field {:disabled true}]]
[form-builder/field-v2 {:field :tax}
"Tax"
[money-field {:disabled true}]
[form-builder/field-v2 {:field :discount}
"Discount"
[money-field {:type "money"
:field [:discount]
:disabled true}]]]
[money-field {:disabled true}]]]
[form-builder/field "Returns"
[money-field {:type "money"
:field [:returns]
:disabled true}]]
[form-builder/field-v2 {:field :returns}
"Returns"
[money-field {:disabled true}]]
[form-builder/field "Service Charge"
[money-field {:type "money"
:field [:service-charge]
:disabled true}]]
[form-builder/field-v2 {:field :service-charge}
"Service Charge"
[money-field {:disabled true}]]
[form-builder/field
[form-builder/field-v2 {:field :tip}
"Tip"
[money-field {:type "money"
:field [:tip]
:disabled true}]]
[money-field {:disabled true}]]
[form-builder/section {:title "Charges"}
[:ul
(for [charge (:charges data)]
^{:key (:id charge)}
[:li (:type-name charge) ": " (:total charge)])]]
[form-builder/section {:title "Line Items"}
[:ul
(for [line-item (:line-items data)]
^{:key (:item-name line-item)}
[:li (:item-name line-item) ": " (:total line-item) [:span.tag (:category line-item)]])]]]])])

View File

@@ -112,7 +112,6 @@
{:id ::manual-import
:events #{::manual/import-completed}
:event-fn (fn [[_ result]]
(println result)
[::status/info ::manual-import
(str "Successfully "
(str/join ", "

View File

@@ -3,13 +3,10 @@
[auto-ap.forms :as forms]
[auto-ap.status :as status]
[auto-ap.subs :as subs]
[auto-ap.views.components.button-radio :refer [button-radio]]
[auto-ap.views.components.expense-accounts-field
:as expense-accounts-field
:refer [expense-accounts-field]]
:refer [expense-accounts-field-v2]]
[auto-ap.views.components.modal :as modal]
[auto-ap.views.components.typeahead.vendor
:refer [search-backed-typeahead]]
[auto-ap.views.pages.data-page :as data-page]
[auto-ap.views.pages.transactions.common
:refer [data-params->query-params]]
@@ -20,7 +17,10 @@
[vimsical.re-frame.fx.track :as track]
[auto-ap.events :as events]
[vimsical.re-frame.cofx.inject :as inject]
[auto-ap.forms.builder :as form-builder]))
[auto-ap.forms.builder :as form-builder]
[malli.core :as m]
[auto-ap.schema :as schema]
[auto-ap.views.components :as com]))
(re-frame/reg-sub
::can-submit
@@ -106,6 +106,11 @@
(fn []
{::track/dispose {:id ::vendor-change}}))
(def bulk-update-schema
(m/schema
[:map
[:vendor schema/reference]]))
(defn form-content [_]
(let [{:keys [data]} @(re-frame/subscribe [::forms/form ::form])]
[form-builder/builder {:submit-event [::code-selected]
@@ -114,33 +119,28 @@
:id ::form}
[form-builder/field "Vendor"
[search-backed-typeahead {:search-query (fn [i]
[:search_vendor
{:query i}
[:name :id]])
:type "typeahead-v3"
:auto-focus true
:field [:vendor]}]]
[form-builder/field-v2 {:field :vendor}
"Vendor"
[com/search-backed-typeahead {:search-query (fn [i]
[:search_vendor
{:query i}
[:name :id]])
:auto-focus true}]]
[form-builder/field
[form-builder/field-v2 {:field [:transaction-approval-status]}
"Approval Status"
[button-radio
{:type "button-radio"
:field [:transaction-approval-status]
:options [[:unapproved "Unapproved"]
[com/button-radio-input
{:options [[:unapproved "Unapproved"]
[:requires-feedback "Client Review"]
[:approved "Approved"]
[:excluded "Excluded from Ledger"]]}]]
[form-builder/raw-field
[expense-accounts-field {:type "expense-accounts"
:descriptor "account asssignment"
:percentage-only? true
:client (:client data)
:locations (into ["Shared"] @(re-frame/subscribe [::subs/locations-for-client (:id (:client data))]))
:max 100
:field [:accounts]}]]]))
[form-builder/raw-field-v2 {:field :accounts}
[expense-accounts-field-v2 {:descriptor "account asssignment"
:percentage-only? true
:client (:client data)
:locations (into ["Shared"] @(re-frame/subscribe [::subs/locations-for-client (:id (:client data))]))
:max 100}]]]))
(defn form [_]
(r/create-class
{:display-name "transaction-bulk-update-form"

View File

@@ -1,26 +1,31 @@
(ns auto-ap.views.pages.transactions.form
(:require
[auto-ap.events :as events]
[auto-ap.forms :as forms]
[auto-ap.forms.builder :as form-builder]
[auto-ap.schema :as schema]
[auto-ap.status :as status]
[auto-ap.subs :as subs]
[auto-ap.views.components.button-radio :refer [button-radio]]
[auto-ap.views.components :as com]
[auto-ap.views.components.expense-accounts-field
:as expense-accounts-field
:refer [expense-accounts-field]]
:refer [expense-accounts-field-v2]]
[auto-ap.views.components.layouts :as layouts]
[auto-ap.views.components.typeahead :refer [typeahead-v3]]
[auto-ap.views.components.typeahead.vendor
:refer [search-backed-typeahead]]
[auto-ap.views.pages.transactions.common :refer [transaction-read]]
[auto-ap.views.utils
:refer [->$ date->str date-picker dispatch-event pretty with-user]]
[clojure.string :as str]
[malli.core :as m]
[re-frame.core :as re-frame]
[react :as react]
[reagent.core :as r]
[vimsical.re-frame.fx.track :as track]
[auto-ap.events :as events]
[auto-ap.forms.builder :as form-builder]))
[vimsical.re-frame.fx.track :as track]))
(def schema
(m/schema [:map
[:vendor schema/reference]
[:accounts expense-accounts-field/schema]
[:approval-status schema/approval-status]]))
;; SUBS
(re-frame/reg-sub
@@ -45,13 +50,6 @@
accounts)}}
transaction-read]}]}))
(re-frame/reg-sub
::can-submit
:<- [::forms/form ::form]
(fn [{:keys [status]} _]
(not= :loading status)))
;; EVENTS
(re-frame/reg-event-db
@@ -300,7 +298,6 @@
(defonce ^js/React.Context current-tab-context ( react/createContext "default"))
(def ^js/React.Provider CurrentTabProvider (. current-tab-context -Provider))
#_(println "Provider is" Provider)
(def ^js/React.Consumer CurrentTabConsumer (. current-tab-context -Consumer))
(defn tabs [props & _]
@@ -343,33 +340,30 @@
should-disable-for-client? (and (not (or is-admin? is-power-user?))
(not= :requires-feedback (:original-status data)))
is-already-matched? (:payment data)]
[form-builder/builder {:can-submit [::can-submit]
:change-event [::changed]
[form-builder/builder {:change-event [::changed]
:submit-event [::saving ]
:id ::form}
:id ::form
:schema schema}
[form-builder/section {:title "Transaction"}
[:<>
(when is-admin?
[form-builder/field
[form-builder/field-v2 {:field [:matched-rule :note] }
"Matched Rule"
[:input.input {:type "text"
:field [:matched-rule :note]
:disabled "disabled"}]])
[form-builder/field "Amount"
[:input.input {:type "text" :disabled "disabled"}]])
[form-builder/field-v2 {:field :amount}
"Amount"
[:input.input {:type "text"
:field [:amount]
:disabled "disabled"}]]
[form-builder/field
[form-builder/field-v2 {:field [:description-original]}
"Description"
[:input.input {:type "text"
:field [:description-original]
:disabled "disabled"}]]
[form-builder/field "Date"
[date-picker {:type "date"
:field [:date]
[form-builder/field-v2 {:field [:date]}
"Date"
[date-picker {
:disabled "disabled"}]]
@@ -407,43 +401,36 @@
[tab {:title "Details" :key :details}
[:div
[form-builder/field
[form-builder/field-v2 {:field :vendor}
"Vendor"
[search-backed-typeahead {:search-query (fn [i]
[:search_vendor
{:query i}
[:name :id]])
:type "typeahead-v3"
:auto-focus true
:field [:vendor]
:disabled (or (boolean (:payment data))
should-disable-for-client?)}]]
[form-builder/raw-field [expense-accounts-field
{:type "expense-accounts"
:field [:accounts]
:max (Math/abs (js/parseFloat (:amount data)))
:descriptor "credit account"
:client (:client data)
:disabled (or (boolean (:payment data))
should-disable-for-client?)
:locations locations}]]
[form-builder/field
[com/search-backed-typeahead {:search-query (fn [i]
[:search_vendor
{:query i}
[:name :id]])
:auto-focus true
:disabled (or (boolean (:payment data))
should-disable-for-client?)}]]
[form-builder/raw-field-v2 {:field :accounts}
[expense-accounts-field-v2
{:max (Math/abs (js/parseFloat (:amount data)))
:descriptor "credit account"
:client (:client data)
:disabled (or (boolean (:payment data))
should-disable-for-client?)
:locations locations}]]
[form-builder/field-v2 {:field :approval-status}
"Approval Status"
[button-radio
{:type "button-radio"
:field [:approval-status]
:options [[:unapproved "Unapproved"]
[com/button-radio-input
{:options [[:unapproved "Unapproved"]
[:requires-feedback "Client Review"]
[:approved "Approved"]
[:excluded "Excluded from Ledger"]]
:disabled should-disable-for-client?}]]
[form-builder/field
[form-builder/field-v2 {:field [:forecast-match]}
"Forecasted-transaction"
[typeahead-v3 {:entities @(re-frame/subscribe [::subs/forecasted-transactions-for-client (:id (:client data))])
:entity->text :identifier
:type "typeahead-v3"
:field [:forecast-match]}]]
[com/entity-typeahead {:entities @(re-frame/subscribe [::subs/forecasted-transactions-for-client (:id (:client data))])
:entity->text :identifier}]]
[form-builder/error-notification]
(when-not should-disable-for-client?
[form-builder/submit-button "Save"])]]]]]])])

View File

@@ -6,7 +6,9 @@
[auto-ap.views.components.modal :as modal]
[auto-ap.views.utils :refer [dispatch-event with-user]]
[re-frame.core :as re-frame]
[auto-ap.forms.builder :as form-builder]))
[auto-ap.forms.builder :as form-builder]
[auto-ap.schema :as schema]
[malli.core :as m]))
(re-frame/reg-sub
::can-submit
@@ -14,15 +16,18 @@
(fn [{ {:keys [data]} :data}]
(not-empty data)))
(defn form []
[form-builder/builder {:submit-event [::save]
:can-submit [::can-submit]
:id ::form}
(def schema
(m/schema [:map [:data schema/not-empty-string]]))
[form-builder/field {:required? true}
(defn form []
[form-builder/builder {:submit-event [::try-save]
:id ::form
:schema schema}
[form-builder/field-v2 {:required? true
:field :data}
"Yodlee manual import table"
[:div.control
[:textarea.textarea {:field [:data]}]]]
[:textarea.textarea ]]
[form-builder/hidden-submit-button]])
(re-frame/reg-event-fx
@@ -33,8 +38,7 @@
:confirm {:value "Import"
:status-from [::status/single ::form]
:class "is-primary"
:on-click (dispatch-event [::save])
:can-submit [::can-submit]
:on-click (dispatch-event [::try-save])
:close-event [::status/completed ::form]}}]
:db (-> db
(forms/start-form ::form
@@ -59,6 +63,15 @@
:uri (str "/api/transactions/batch-upload")
:on-success [::import-completed]}})))
(re-frame/reg-event-fx
::try-save
[(forms/in-form ::form)]
(fn [{:keys [db]}]
(if (not (m/validate schema (:data db)))
{:dispatch-n [[::status/error ::form [{:message "Please correct any errors and try again"}]]
[::forms/attempted-submit ::form]]}
{:dispatch [::save]})))

View File

@@ -1,32 +1,35 @@
(ns auto-ap.views.pages.transactions.table
(:require [auto-ap.events :as events]
[auto-ap.subs :as subs]
[auto-ap.views.components.dropdown
:refer
[drop-down drop-down-contents]]
[auto-ap.views.components.grid :as grid]
[auto-ap.views.pages.transactions.form :as edit]
[auto-ap.views.utils
:refer
[action-cell-width date->str dispatch-event dispatch-event-with-propagation nf pretty with-role]]
[goog.string :as gstring]
[re-frame.core :as re-frame]
[auto-ap.views.components.buttons :as buttons]
[auto-ap.status :as status]
[auto-ap.views.pages.data-page :as data-page]
[bidi.bidi :as bidi]
[cemerick.url :as url]
[auto-ap.routes :as routes]))
(:require
[auto-ap.events :as events]
[auto-ap.routes :as routes]
[auto-ap.status :as status]
[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.pages.transactions.form :as edit]
[auto-ap.views.utils
:refer [action-cell-width
date->str
dispatch-event-with-propagation
nf
pretty
with-role]]
[bidi.bidi :as bidi]
[cemerick.url :as url]
[re-frame.core :as re-frame]))
(re-frame/reg-event-fx
::editing-matches-found
(fn [{:keys [db]} [_ which matches]]
(fn [_ [_ which matches]]
{:dispatch
[::edit/editing which (:potential-payment-matches matches) (:potential-autopay-invoices-matches matches) (:potential-unpaid-invoices-matches matches) (:potential-transaction-rule-matches matches)]}))
(re-frame/reg-event-fx
::editing-matches-failed
(fn [{:keys [db]} [_ which payment-matches]]
(fn [_ [_ which payment-matches]]
{:dispatch
[::edit/editing which payment-matches]}))
@@ -71,12 +74,10 @@
(fn [{table-params :db} [_ params :as z]]
{:db (merge table-params params)}))
(defn table [{:keys [id data-page check-boxes?]}]
(defn table [{:keys [data-page check-boxes?]}]
(let [selected-client @(re-frame/subscribe [::subs/client])
{:keys [data status params]} @(re-frame/subscribe [::data-page/page data-page])
states @(re-frame/subscribe [::status/multi ::edits])
is-power-user? @(re-frame/subscribe [::subs/is-power-user?])
is-admin? @(re-frame/subscribe [::subs/is-admin?])]
{:keys [data params]} @(re-frame/subscribe [::data-page/page data-page])
states @(re-frame/subscribe [::status/multi ::edits])]
[grid/grid {:data-page data-page
:column-count (if selected-client 6 7)
:check-boxes? check-boxes?}
@@ -94,7 +95,7 @@
[grid/sortable-header-cell {:sort-key "status" :sort-name "Status" :style {:width "7em"}} "Status"]
[grid/header-cell {:style {:width (action-cell-width 3)}}]]]
[grid/body
(for [{:keys [client account vendor approval-status payment expected-deposit status bank-account description-original date amount id yodlee-merchant ] :as i} (:data data)]
(for [{:keys [client vendor payment expected-deposit status bank-account description-original date amount id yodlee-merchant ] :as i} (:data data)]
^{:key id}
[grid/row {:class (:class i) :id id :entity i}
(when-not selected-client