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/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/vendor [:db/id :vendor/name]
:transaction/matched-rule [:db/id :transaction-rule/note] :transaction/matched-rule [:db/id :transaction-rule/note]
:transaction/forecast-match [:db/id :forecasted-transaction/identifier]
:transaction/accounts [:transaction-account/amount :transaction/accounts [:transaction-account/amount
:db/id :db/id
:transaction-account/location :transaction-account/location

View File

@@ -100,12 +100,6 @@
(re-frame/reg-event-db (re-frame/reg-event-db
::check-problems ::check-problems
(fn [db [_ form schema]] (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] (assoc-in db [::forms form :problems]
(when schema (m/explain schema (get-in db [::forms form :data])))))) (when schema (m/explain schema (get-in db [::forms form :data]))))))

View File

@@ -89,11 +89,13 @@
(into [:fieldset {:disabled (boolean (= :loading (:state status)))}] (into [:fieldset {:disabled (boolean (= :loading (:state status)))}]
(r/children (r/current-component)))] (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 [] (defn virtual-builder []
(let [starting-key (random-uuid) (let [starting-key (random-uuid)
key (r/atom starting-key)] 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] (let [data-sub [::forms/form @key]
{:keys [data error problems visited]} @(re-frame/subscribe data-sub) {:keys [data error problems visited]} @(re-frame/subscribe data-sub)
data (or value data)] data (or value data)]
@@ -101,11 +103,12 @@
:error-messages (or error-messages :error-messages (or error-messages
nil) nil)
;; wrap to make sure raw form updates too ;; 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]) (re-frame/dispatch-sync [::forms/reset @key v])
(on-change v)) (on-change v o))
:blur-event [::blurred schema @key ] :blur-event [::blurred schema @key ]
:problems problems :problems problems
:attempted-submit? attempted-submit?
:visited visited :visited visited
:error error :error error
:id @key :id @key
@@ -206,7 +209,6 @@
nil) nil)
visited? (get visited full-field-path) visited? (get visited full-field-path)
value (get-in data full-field-path)] value (get-in data full-field-path)]
(println "VISITED " visited full-field-path problems)
(-> child-props (-> child-props
(assoc :on-change (assoc :on-change
(if on-change (if on-change
@@ -246,22 +248,6 @@
label)]) label)])
(into [:div.control ] children)])))) (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 [] (defn field-v2 []
(let [props (r/props (r/current-component)) (let [props (r/props (r/current-component))
[label child] (r/children (r/current-component))] [label child] (r/children (r/current-component))]
@@ -280,23 +266,6 @@
[:div [:div
[raw-error-v2 {:field (:field props)}]]])))) [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]}] (defn section [{:keys [title]}]
[:<> [:<>
[:h4.is-4.title title] [:h4.is-4.title title]

View File

@@ -21,3 +21,6 @@
[:account reference] [:account reference]
[:location :string] [:location :string]
[:amount money]])) [: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.multi :as multi]
[auto-ap.views.components.money-field :as money] [auto-ap.views.components.money-field :as money]
[auto-ap.views.components.number :as number] [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 (defn checkbox [{:keys [on-change
@@ -49,6 +50,16 @@
(for [[k v] options] (for [[k v] options]
^{:key k} [:option {:value k} v])]]]) ^{: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 multi-field-v2 multi/multi-field-v2)
(def number-input number/number-input) (def number-input number/number-input)
@@ -58,4 +69,4 @@
(def search-backed-typeahead typeahead/search-backed-typeahead) (def search-backed-typeahead typeahead/search-backed-typeahead)
(def entity-typeahead typeahead/typeahead-v3) (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 :schema schema
:on-change (fn [expense-accounts original-expense-accounts] :on-change (fn [expense-accounts original-expense-accounts]
(let [updated-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 (cond-> after-account
(not= (:id (:account before-account)) (not= (:id (:account before-account))
(:id (:account after-account))) (:id (:account after-account)))

View File

@@ -9,7 +9,8 @@
[auto-ap.forms.builder :as form-builder])) [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) (let [prop-value (if (seq prop-value)
prop-value prop-value
[])] [])]
@@ -18,17 +19,23 @@
:on-change on-change} :on-change on-change}
[:fieldset {:disabled disabled} [:fieldset {:disabled disabled}
[:div {:style {:margin-bottom "0.25em"}} [:div {:style {:margin-bottom "0.25em"}}
(into [appearing-group] (into [(if key-fn
appearing-group
[:<>])]
(for [[i override] (map vector (range) prop-value) (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?) is-disabled? (boolean (and (= false allow-change?)
extant?))]] extant?))]]
^{:key (or (key-fn override) ^{:key (or (when key-fn (key-fn override))
(::key override))} (::key override)
i)}
[form-builder/with-scope {:scope [i]} [form-builder/with-scope {:scope [i]}
^{:key (or (key-fn override) ^{:key (or (when key-fn (key-fn override))
(::key override))} (::key override)
i)}
[:div.level {:style {:margin-bottom "0.25em"}} [:div.level {:style {:margin-bottom "0.25em"}}
[:div.level-left {:style {:padding "0.5em 1em"} [:div.level-left {:style {:padding "0.5em 1em"}
:class (when-not extant? :class (when-not extant?

View File

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

View File

@@ -11,29 +11,6 @@
[malli.core :as m] [malli.core :as m]
[re-frame.core :as re-frame])) [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 (def client-schema
(m/schema [:map [:client schema/reference]])) (m/schema [:map [:client schema/reference]]))
@@ -46,11 +23,40 @@
[:maybe [:maybe
[:sequential client-schema]]]])) [: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 [] (defn form []
(let [{:keys [data]} @(re-frame/subscribe [::forms/form ::form]) (let [{:keys [data]} @(re-frame/subscribe [::forms/form ::form])
clients @(re-frame/subscribe [::subs/clients])] clients @(re-frame/subscribe [::subs/clients])]
(println data)
[:<> [:<>
[form-builder/builder {:submit-event [::saving] [form-builder/builder {:submit-event [::saving]
:id ::form :id ::form

View File

@@ -1,43 +1,40 @@
(ns auto-ap.views.pages.admin.vendors.merge-dialog (ns auto-ap.views.pages.admin.vendors.merge-dialog
(:require (:require
[auto-ap.forms :as forms] [auto-ap.forms :as forms]
[auto-ap.forms.builder :as form-builder]
[auto-ap.schema :as schema]
[auto-ap.status :as status] [auto-ap.status :as status]
[auto-ap.subs :as subs] [auto-ap.subs :as subs]
[auto-ap.views.components :as com]
[auto-ap.views.components.modal :as modal] [auto-ap.views.components.modal :as modal]
[auto-ap.views.components.typeahead.vendor
:refer [search-backed-typeahead]]
[auto-ap.views.utils :refer [dispatch-event]] [auto-ap.views.utils :refer [dispatch-event]]
[re-frame.core :as re-frame] [malli.core :as m]
[auto-ap.forms.builder :as form-builder])) [re-frame.core :as re-frame]))
(re-frame/reg-sub (def merge-schema
::can-submit (m/schema [:map
:<- [::forms/form ::form] [:from schema/reference]
(fn [{:keys [data]}] [:to schema/reference]]))
(and (:from data)
(:to data))))
(defn form [] (defn form []
[form-builder/builder {:submit-event [::save] [form-builder/builder {:submit-event [::try-save]
:can-submit [::can-submit] :id ::form
:id ::form} :schema merge-schema}
[form-builder/field "Form Vendor (will be deleted)" [form-builder/field-v2 {:field :from}
[search-backed-typeahead {:search-query (fn [i] "Form Vendor (will be deleted)"
[:search_vendor [com/search-backed-typeahead {:search-query (fn [i]
{:query i} [:search_vendor
[:name :id]]) {:query i}
:type "typeahead-v3" [:name :id]])
:auto-focus true :auto-focus true}]]
:field [:from]}]]
[form-builder/field "To Vendor" [form-builder/field-v2 {:field :to}
[search-backed-typeahead {:search-query (fn [i] "To Vendor"
[:search_vendor [com/search-backed-typeahead {:search-query (fn [i]
{:query i} [:search_vendor
[:name :id]]) {:query i}
:type "typeahead-v3" [:name :id]])}]]
:field [:to]}]]
[form-builder/hidden-submit-button]]) [form-builder/hidden-submit-button]])
(re-frame/reg-event-fx (re-frame/reg-event-fx
@@ -48,8 +45,7 @@
:confirm {:value "Merge" :confirm {:value "Merge"
:status-from [::status/single ::form] :status-from [::status/single ::form]
:class "is-primary" :class "is-primary"
:on-click (dispatch-event [::save]) :on-click (dispatch-event [::try-save])
:can-submit [::can-submit]
:close-event [::status/completed ::form]}}] :close-event [::status/completed ::form]}}]
:db (forms/start-form db ::form {})})) :db (forms/start-form db ::form {})}))
@@ -73,3 +69,12 @@
{:from (:id from) :to (:id to)} []]}]} {:from (:id from) :to (:id to)} []]}]}
:on-success [::complete]}}))) :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 (:require
[auto-ap.forms :as forms] [auto-ap.forms :as forms]
[auto-ap.forms.builder :as form-builder] [auto-ap.forms.builder :as form-builder]
[auto-ap.schema :as schema]
[auto-ap.status :as status] [auto-ap.status :as status]
[auto-ap.subs :as subs] [auto-ap.subs :as subs]
[auto-ap.views.components :as com]
[auto-ap.views.components.modal :as modal] [auto-ap.views.components.modal :as modal]
[auto-ap.views.components.money-field :refer [money-field]]
[auto-ap.views.pages.invoices.common [auto-ap.views.pages.invoices.common
:refer [does-amount-exceed-outstanding? invoice-read]] :refer [does-amount-exceed-outstanding? invoice-read]]
[auto-ap.views.components.money-field :refer [money-field]] [auto-ap.views.utils :refer [coerce-float dispatch-event with-user]]
[auto-ap.views.utils :refer [dispatch-event horizontal-field with-user]]
[re-frame.core :as re-frame]
[auto-ap.views.components :as com]
[malli.core :as m] [malli.core :as m]
[auto-ap.schema :as schema])) [malli.error :as me]
[re-frame.core :as re-frame]))
(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)))
(def advanced-print-schema (m/schema (def advanced-print-schema (m/schema
[:map [:and
[:bank-account-id schema/not-empty-string]])) [: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 [] (defn form []
(let [real-bank-accounts @(re-frame/subscribe [::subs/real-bank-accounts]) (let [real-bank-accounts @(re-frame/subscribe [::subs/real-bank-accounts])
{:keys [data]} @(re-frame/subscribe [::forms/form ::form])] {:keys [data]} @(re-frame/subscribe [::forms/form ::form])]
(println "TEST?")
[form-builder/builder {:submit-event [::try-save] [form-builder/builder {:submit-event [::try-save]
:can-submit [::can-submit]
:id ::form :id ::form
:schema advanced-print-schema} :schema advanced-print-schema}
[:div.field [form-builder/field-v2 {:field :bank-account-id}
[:label.label "Pay using"] "Pay using"
[:div.control [com/select-field {:options (for [{:keys [id name]} real-bank-accounts]
[:span.select
[form-builder/raw-field-v2 {:field :bank-account-id}
[com/select-field {:options (for [{:keys [id name]} real-bank-accounts]
[id name]) [id name])
:allow-nil? true}]]]]] :allow-nil? true}]]
[:table.table.is-fullwidth [:table.table.is-fullwidth
[:thead [:thead
@@ -64,14 +53,14 @@
[:th {:style {"width" "10em"}} "Payment"]]] [:th {:style {"width" "10em"}} "Payment"]]]
[:tbody [:tbody
(doall (doall
(for [{:keys [vendor invoice-number id] :as i} (:invoices data)] (for [{:keys [vendor invoice-number id]} (:invoices data)]
^{:key id} ^{:key id}
[:tr [:tr
[:td (:name vendor)] [:td (:name vendor)]
[:td invoice-number] [:td invoice-number]
[:td [:td
[form-builder/raw-field-v2 {:field [:invoice-amounts :id :amount]} [form-builder/raw-field-v2 {:field [:invoice-amounts id :amount]}
[money-field]]]]))]]])) [money-field]]]]))]]]))
(re-frame/reg-event-fx (re-frame/reg-event-fx
@@ -83,14 +72,13 @@
:status-from [::status/single ::form] :status-from [::status/single ::form]
:class "is-primary" :class "is-primary"
:on-click (dispatch-event [::try-save]) :on-click (dispatch-event [::try-save])
:can-submit [::can-submit]
:close-event [::status/completed ::form]}}] :close-event [::status/completed ::form]}}]
:db (-> db :db (-> db
(forms/start-form ::form (forms/start-form ::form
{:invoices invoices {:invoices invoices
:invoice-amounts (into {} :invoice-amounts (into {}
(map (fn [i] [(:id i) (map (fn [i] [(:id i)
{:amount (:outstanding-balance i)}]) {:amount (coerce-float (:outstanding-balance i))}])
invoices))}))})) invoices))}))}))
@@ -115,7 +103,7 @@
first first
:type) :type)
:check) :check)
{:keys [date invoices invoice-amounts check-number bank-account-id client]} (:data db)] {:keys [invoices invoice-amounts bank-account-id]} (:data db)]
{:graphql {:graphql
{:token user {:token user
:owns-state {:single ::form} :owns-state {:single ::form}
@@ -139,6 +127,6 @@
(re-frame/reg-event-fx (re-frame/reg-event-fx
::checks-printed ::checks-printed
(fn [{:keys [db]} [_ data]] (fn [{:keys [_]} [_ _]]
{:dispatch [::modal/modal-closed]})) {:dispatch [::modal/modal-closed]}))

View File

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

View File

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

View File

@@ -24,7 +24,8 @@
[vimsical.re-frame.fx.track :as track] [vimsical.re-frame.fx.track :as track]
[vimsical.re-frame.cofx.inject :as inject] [vimsical.re-frame.cofx.inject :as inject]
[auto-ap.views.pages.ledger.report-table :as rtable] [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] (defn data-params->query-params [params]
(when 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-left
[:div.level-item [:div.level-item
[:div.control [:div.control
[form-builder/field [form-builder/field-v2 {:field :date}
"Date" "Date"
[date-picker {:output :cljs-date [date-picker {:output :cljs-date}]]]]
:type "date"
:field [:date]}]]]]
[:div.level-item [:div.level-item
[form-builder/field [form-builder/field-v2 {:field :include-comparison}
[:div.mt-5] [:div.mt-5]
[switch-field {:id "include-comparison" [com/switch-input {:id "include-comparison"
:field [:include-comparison] :label "Include compariison"}]]]
:label "Include compariison"
:type "checkbox"}]]]
[:div.level-item [:div.level-item
(when (boolean (:include-comparison data)) (when (boolean (:include-comparison data))
[form-builder/field [form-builder/field-v2 {:field :comparison-date}
"Comparison Date" "Comparison Date"
[date-picker {:output :cljs-date [date-picker {:output :cljs-date}]])]]
:type "date"
:field [:comparison-date]}]])]]
[:div.level-right [:div.level-right
[:div.buttons [:div.buttons

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -6,7 +6,9 @@
[auto-ap.views.components.modal :as modal] [auto-ap.views.components.modal :as modal]
[auto-ap.views.utils :refer [dispatch-event with-user]] [auto-ap.views.utils :refer [dispatch-event with-user]]
[re-frame.core :as re-frame] [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 (re-frame/reg-sub
::can-submit ::can-submit
@@ -14,15 +16,18 @@
(fn [{ {:keys [data]} :data}] (fn [{ {:keys [data]} :data}]
(not-empty data))) (not-empty data)))
(defn form [] (def schema
[form-builder/builder {:submit-event [::save] (m/schema [:map [:data schema/not-empty-string]]))
:can-submit [::can-submit]
:id ::form}
[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" "Yodlee manual import table"
[:div.control [:textarea.textarea ]]
[:textarea.textarea {:field [:data]}]]]
[form-builder/hidden-submit-button]]) [form-builder/hidden-submit-button]])
(re-frame/reg-event-fx (re-frame/reg-event-fx
@@ -33,8 +38,7 @@
:confirm {:value "Import" :confirm {:value "Import"
:status-from [::status/single ::form] :status-from [::status/single ::form]
:class "is-primary" :class "is-primary"
:on-click (dispatch-event [::save]) :on-click (dispatch-event [::try-save])
:can-submit [::can-submit]
:close-event [::status/completed ::form]}}] :close-event [::status/completed ::form]}}]
:db (-> db :db (-> db
(forms/start-form ::form (forms/start-form ::form
@@ -59,6 +63,15 @@
:uri (str "/api/transactions/batch-upload") :uri (str "/api/transactions/batch-upload")
:on-success [::import-completed]}}))) :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 (ns auto-ap.views.pages.transactions.table
(:require [auto-ap.events :as events] (:require
[auto-ap.subs :as subs] [auto-ap.events :as events]
[auto-ap.views.components.dropdown [auto-ap.routes :as routes]
:refer [auto-ap.status :as status]
[drop-down drop-down-contents]] [auto-ap.subs :as subs]
[auto-ap.views.components.grid :as grid] [auto-ap.views.components.buttons :as buttons]
[auto-ap.views.pages.transactions.form :as edit] [auto-ap.views.components.dropdown
[auto-ap.views.utils :refer [drop-down drop-down-contents]]
:refer [auto-ap.views.components.grid :as grid]
[action-cell-width date->str dispatch-event dispatch-event-with-propagation nf pretty with-role]] [auto-ap.views.pages.data-page :as data-page]
[goog.string :as gstring] [auto-ap.views.pages.transactions.form :as edit]
[re-frame.core :as re-frame] [auto-ap.views.utils
[auto-ap.views.components.buttons :as buttons] :refer [action-cell-width
[auto-ap.status :as status] date->str
[auto-ap.views.pages.data-page :as data-page] dispatch-event-with-propagation
[bidi.bidi :as bidi] nf
[cemerick.url :as url] pretty
[auto-ap.routes :as routes])) with-role]]
[bidi.bidi :as bidi]
[cemerick.url :as url]
[re-frame.core :as re-frame]))
(re-frame/reg-event-fx (re-frame/reg-event-fx
::editing-matches-found ::editing-matches-found
(fn [{:keys [db]} [_ which matches]] (fn [_ [_ which matches]]
{:dispatch {:dispatch
[::edit/editing which (:potential-payment-matches matches) (:potential-autopay-invoices-matches matches) (:potential-unpaid-invoices-matches matches) (:potential-transaction-rule-matches matches)]})) [::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 (re-frame/reg-event-fx
::editing-matches-failed ::editing-matches-failed
(fn [{:keys [db]} [_ which payment-matches]] (fn [_ [_ which payment-matches]]
{:dispatch {:dispatch
[::edit/editing which payment-matches]})) [::edit/editing which payment-matches]}))
@@ -71,12 +74,10 @@
(fn [{table-params :db} [_ params :as z]] (fn [{table-params :db} [_ params :as z]]
{:db (merge table-params params)})) {: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]) (let [selected-client @(re-frame/subscribe [::subs/client])
{:keys [data status params]} @(re-frame/subscribe [::data-page/page data-page]) {:keys [data params]} @(re-frame/subscribe [::data-page/page data-page])
states @(re-frame/subscribe [::status/multi ::edits]) 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?])]
[grid/grid {:data-page data-page [grid/grid {:data-page data-page
:column-count (if selected-client 6 7) :column-count (if selected-client 6 7)
:check-boxes? check-boxes?} :check-boxes? check-boxes?}
@@ -94,7 +95,7 @@
[grid/sortable-header-cell {:sort-key "status" :sort-name "Status" :style {:width "7em"}} "Status"] [grid/sortable-header-cell {:sort-key "status" :sort-name "Status" :style {:width "7em"}} "Status"]
[grid/header-cell {:style {:width (action-cell-width 3)}}]]] [grid/header-cell {:style {:width (action-cell-width 3)}}]]]
[grid/body [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} ^{:key id}
[grid/row {:class (:class i) :id id :entity i} [grid/row {:class (:class i) :id id :entity i}
(when-not selected-client (when-not selected-client