simplified vendor form.

This commit is contained in:
2022-07-15 07:38:15 -07:00
parent 586978823e
commit d16b9c9a5e
2 changed files with 359 additions and 396 deletions

View File

@@ -73,6 +73,23 @@
[:label.label label])) [:label.label label]))
[:div.control [raw-field {} child]]]))])) [:div.control [raw-field {} child]]]))]))
(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

@@ -5,7 +5,7 @@
[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.address :refer [address-field]] [auto-ap.views.components.address :refer [address2-field]]
[auto-ap.views.components.typeahead.vendor [auto-ap.views.components.typeahead.vendor
:refer [search-backed-typeahead]] :refer [search-backed-typeahead]]
[auto-ap.views.components.modal :as modal] [auto-ap.views.components.modal :as modal]
@@ -18,7 +18,8 @@
with-is-admin? with-is-admin?
with-user]] with-user]]
[clojure.spec.alpha :as s] [clojure.spec.alpha :as s]
[re-frame.core :as re-frame])) [re-frame.core :as re-frame]
[auto-ap.forms.builder :as form-builder]))
(re-frame/reg-sub (re-frame/reg-sub
::can-submit ::can-submit
@@ -26,13 +27,6 @@
(fn [form] (fn [form]
(s/valid? ::entity/vendor (:data form)))) (s/valid? ::entity/vendor (:data form))))
(re-frame/reg-event-db
::settled
[(forms/in-form ::vendor-form)]
(fn [form _]
form))
(re-frame/reg-event-db (re-frame/reg-event-db
::removed-override ::removed-override
[(forms/in-form ::vendor-form)] [(forms/in-form ::vendor-form)]
@@ -72,391 +66,346 @@
{:dispatch [::modal/modal-closed ]})) {:dispatch [::modal/modal-closed ]}))
(re-frame/reg-event-fx (re-frame/reg-event-fx
::save ::save
[with-user with-is-admin? (forms/triggers-loading ::vendor-form) (forms/in-form ::vendor-form)] [with-user with-is-admin? (forms/triggers-loading ::vendor-form) (forms/in-form ::vendor-form)]
(fn [{:keys [user is-admin?] {{:keys [name hidden print-as terms invoice-reminder-schedule primary-contact automatically-paid-when-due schedule-payment-dom secondary-contact address default-account terms-overrides account-overrides id legal-entity-tin legal-entity-tin-type legal-entity-first-name legal-entity-last-name legal-entity-middle-name legal-entity-1099-type] :as data} :data} :db} _] (fn [{:keys [user is-admin?] {{:keys [name hidden print-as terms invoice-reminder-schedule primary-contact automatically-paid-when-due schedule-payment-dom secondary-contact address default-account terms-overrides account-overrides id legal-entity-tin legal-entity-tin-type legal-entity-first-name legal-entity-last-name legal-entity-middle-name legal-entity-1099-type] :as data} :data} :db} _]
(when (s/valid? ::entity/vendor data) (when (s/valid? ::entity/vendor data)
{ :graphql (let [query [:upsert-vendor
{:token user {:vendor (cond-> {:id id
:owns-state {:single ::vendor-form} :name name
:query-obj {:venia/operation {:operation/type :mutation :print-as print-as
:operation/name "UpsertVendor"} :venia/queries [{:query/data [:upsert-vendor :terms terms
{:vendor (cond-> {:id id :default-account-id (:id default-account)
:name name :address address
:print-as print-as :primary-contact primary-contact
:terms terms :secondary-contact secondary-contact
:default-account-id (:id default-account) :invoice-reminder-schedule invoice-reminder-schedule}
:address address :primary-contact primary-contact is-admin? (assoc :hidden hidden
:secondary-contact secondary-contact :terms-overrides (mapv
:invoice-reminder-schedule invoice-reminder-schedule} (fn [{:keys [client override id]}]
is-admin? (assoc :hidden hidden {:id id
:terms-overrides (mapv :client-id (:id client)
(fn [{:keys [client override id]}] :terms override})
{:id id terms-overrides)
:client-id (:id client) :account-overrides (mapv
:terms override}) (fn [{:keys [client override id]}]
terms-overrides) {:id id
:account-overrides (mapv :client-id (:id client)
(fn [{:keys [client override id]}] :account-id (:id override)})
{:id id account-overrides)
:client-id (:id client) :schedule-payment-dom (mapv
:account-id (:id override)}) (fn [{:keys [client override id]}]
account-overrides) {:id id
:schedule-payment-dom (mapv :client-id (:id client)
(fn [{:keys [client override id]}] :dom override})
{:id id schedule-payment-dom)
:client-id (:id client) :automatically-paid-when-due (mapv
:dom override}) :id
schedule-payment-dom) automatically-paid-when-due)
:automatically-paid-when-due (mapv :legal-entity-first-name legal-entity-first-name
:id :legal-entity-middle-name legal-entity-middle-name
automatically-paid-when-due) :legal-entity-last-name legal-entity-last-name
:legal-entity-first-name legal-entity-first-name :legal-entity-tin legal-entity-tin
:legal-entity-middle-name legal-entity-middle-name :legal-entity-tin-type (some-> legal-entity-tin-type clojure.core/name not-empty keyword)
:legal-entity-last-name legal-entity-last-name :legal-entity-1099-type (some-> legal-entity-1099-type clojure.core/name not-empty keyword)
:legal-entity-tin legal-entity-tin ))}
:legal-entity-tin-type (some-> legal-entity-tin-type clojure.core/name not-empty keyword) common/default-read]]
:legal-entity-1099-type (some-> legal-entity-1099-type clojure.core/name not-empty keyword) { :graphql
))} {:token user
common/default-read]}]} :owns-state {:single ::vendor-form}
:on-success [::save-complete]}}))) :query-obj {:venia/operation
{:operation/type :mutation
:operation/name "UpsertVendor"} :venia/queries [{:query/data query}]}
:on-success [::save-complete]}}))))
(defn client-list [{:keys [override-key change-event data]}] (defn client-list [{:keys [override-key data]}]
(let [clients @(re-frame/subscribe [::subs/clients]) (let [clients @(re-frame/subscribe [::subs/clients])]
is-admin? @(re-frame/subscribe [::subs/is-admin?])] [form-builder/horizontal-control
(when is-admin? "Client"
[horizontal-field (doall
[:label.label "Client"] (for [[i override] (map vector (range) (conj (override-key data) {:key (random-uuid)}))]
(doall ^{:key (or (:id override)
(:key override))}
[:div.level
[:div.level-left
[:div.level-item
[form-builder/raw-field
[typeahead-v3 {:entities clients
:entity->text :name
:style {:width "13em"}
:type "typeahead-v3"
:field [override-key i]}]]]
[:div.level-item
[:a.button {:on-click (dispatch-event [::removed-override override-key i])} [:span.icon [:span.icon-remove]]]]]]))]))
(defn default-with-overrides [{:keys [override-key default-key data mandatory?]} template]
(let [clients @(re-frame/subscribe [::subs/clients])]
[:div
[form-builder/horizontal-control
[:span "Default"
(when mandatory?
[:span.has-text-danger " *"])]
(template default-key nil)]
[form-builder/horizontal-control
"Overrides"
(doall
(for [[i override] (map vector (range) (conj (override-key data) {:key (random-uuid)}))] (for [[i override] (map vector (range) (conj (override-key data) {:key (random-uuid)}))]
^{:key (or ^{:key (or
(:id override)
(:key override))}
[:div.columns
[:div.column
[bind-field
[typeahead-v3 {:entities clients
:entity->text :name
:type "typeahead-v3"
:field [override-key i]
:event change-event
:subscription data}]]]
[:div.column.is-1
[:a.button {:on-click (dispatch-event [::removed-override override-key i])} [:span.icon [:span.icon-remove]]]]]))])))
(defn default-with-overrides [{:keys [override-key change-event default-key data mandatory?]} template]
(let [clients @(re-frame/subscribe [::subs/clients])
is-admin? @(re-frame/subscribe [::subs/is-admin?])]
[:div
[horizontal-field
[:label.label [:span "Default"
(when mandatory?
[:span.has-text-danger " *"])]]
[bind-field
(template default-key nil)
#_(assoc-in template [1 :field ] default-key)]]
(when is-admin?
[horizontal-field
[:label.label "Overrides"]
(doall
(for [[i override] (map vector (range) (conj (override-key data) {:key (random-uuid)}))]
^{:key (or
(:id override) (:id override)
(:key override))} (:key override)
[:div.columns )}
[:div.column [:div.level
[bind-field [:div.level-left
[typeahead-v3 {:entities clients [:div.level-item
[form-builder/raw-field
[typeahead-v3 {:entities clients
:entity->text :name :entity->text :name
:type "typeahead-v3" :style {:width "13em"}
:field [override-key i :client] :type "typeahead-v3"
:event change-event :field [override-key i :client]}]]]
:subscription data}]]] [:div.level-item
[:div.column (template
[bind-field
(template
[override-key i :override] [override-key i :override]
(get-in data [override-key i :client]) (get-in data [override-key i :client]))]
)]] [:div.level-item
[:div.column.is-1 [:a.button {:on-click (dispatch-event [::removed-override override-key i])} [:span.icon [:span.icon-remove]]]]]]))]]))
[:a.button {:on-click (dispatch-event [::removed-override override-key i])} [:span.icon [:span.icon-remove]]]]]))])]))
(defn client-overrides [{:keys [override-key change-event data]} template] (defn client-overrides [{:keys [override-key data]} template]
(let [clients @(re-frame/subscribe [::subs/clients]) (let [clients @(re-frame/subscribe [::subs/clients])]
is-admin? @(re-frame/subscribe [::subs/is-admin?])] [form-builder/horizontal-control
(when is-admin? "Overrides"
[horizontal-field (doall
[:label.label "Overrides"] (for [[i override] (map vector (range) (conj (override-key data) {:key (random-uuid)}))]
(doall ^{:key (or
(for [[i override] (map vector (range) (conj (override-key data) {:key (random-uuid)}))]
^{:key (or
(:id override) (:id override)
(:key override))} (:key override))}
[:div.columns [:div.level
[:div.column [:div.level-left
[bind-field [:div.level-item
[typeahead-v3 {:entities clients [form-builder/raw-field
[typeahead-v3 {:entities clients
:entity->text :name :entity->text :name
:type "typeahead-v3" :style {:width "13em"}
:field [override-key i :client] :type "typeahead-v3"
:event change-event :field [override-key i :client]}]]]
:subscription data}]]] [:div.level-item
[:div.column (template
[bind-field
(template
[override-key i :override] [override-key i :override]
(get-in data [override-key i :client]) (get-in data [override-key i :client]))]
)]] [:div.level-item
[:div.column.is-1 [:a.button {:on-click (dispatch-event [::removed-override override-key i])} [:span.icon [:span.icon-remove]]]]]]))]))
[:a.button {:on-click (dispatch-event [::removed-override override-key i])} [:span.icon [:span.icon-remove]]]]]))])))
(defn form-content [{:keys [data]}]
(defn form-content [{:keys [data change-event]}]
(let [is-admin? @(re-frame/subscribe [::subs/is-admin?])] (let [is-admin? @(re-frame/subscribe [::subs/is-admin?])]
[:div [form-builder/builder {:submit-event [::save]
[horizontal-field :can-submit [::can-submit]
[:label.label [:span "Name " :change-event [::changed]
[:span.has-text-danger "*"]]] :id ::vendor-form}
[:div.control [:div
[bind-field [form-builder/horizontal-field
[:input.input {:type "text" [:span "Name " [:span.has-text-danger "*"]]
:auto-focus true [:input.input {:type "text"
:field :name :auto-focus true
:spec ::entity/name :field :name
:event change-event :spec ::entity/name}]]
:subscription data}]]]]
[horizontal-field [form-builder/horizontal-field
[:label.label "Print Checks As"] "Print Checks As"
[:div.control [:input.input {:type "text"
[bind-field :field :print-as
[:input.input {:type "text" :spec ::entity/print-as}]]
:field :print-as (when is-admin?
:spec ::entity/print-as [form-builder/horizontal-field
:event change-event "Hidden"
:subscription data}]]]] [:input {:type "checkbox"
:field :hidden
:spec ::entity/hidden}]])
(when is-admin? (if is-admin?
[horizontal-field [:<>
[:label.label "Hidden"] [form-builder/section {:title "Terms"}
[:div.control [default-with-overrides {:data data
[bind-field :default-key :terms
[:input {:type "checkbox" :override-key :terms-overrides}
:field :hidden (fn [field _]
:spec ::entity/hidden [form-builder/raw-field
:event change-event [:input.input {:type "number"
:subscription data}]]]]) :step "1"
[:h2.subtitle "Terms"] :style {:width "4em"}
[default-with-overrides {:data data :change-event change-event :field field
:default-key :terms :size 3
:override-key :terms-overrides} :spec ::entity/terms}]])]]]
(fn [field _]
[:input.input {:type "number"
:step "1"
:style {:width "4em"}
:field field
:size 3
:spec ::entity/terms
:event change-event
:subscription data}])]
(when is-admin? [form-builder/horizontal-field
[:h2.subtitle "Schedule payment when due"]) [:span "Terms"]
[client-list {:data data :change-event change-event [:input.input {:type "number"
:override-key :automatically-paid-when-due}] :step "1"
:style {:width "4em"}
:field :terms
:size 3
:spec ::entity/terms}]])
(when is-admin? (when is-admin?
[:h2.subtitle "Schedule payment on day of month"]) [form-builder/section {:title "Schedule payment when due"}
[client-overrides {:data data :change-event change-event [client-list {:data data
:mandatory? true :override-key :automatically-paid-when-due}]])
:override-key :schedule-payment-dom}
(fn [field _]
[:input.input {:type "number"
:step "1"
:style {:width "5em"}
:field field
:size 3
:spec ::entity/dom
:event change-event
:subscription data}])]
[:h2.subtitle "Expense Accounts"] (when is-admin?
[default-with-overrides {:data data :change-event change-event [form-builder/section {:title "Schedule payment on day of month"}
:mandatory? true [client-overrides {:data data
:default-key :default-account :mandatory? true
:override-key :account-overrides} :override-key :schedule-payment-dom}
(fn [field client] (fn [field _]
[search-backed-typeahead {:search-query (fn [i] [form-builder/raw-field
[:search_account [:input.input {:type "number"
{:query i :step "1"
:client-id (:id client)} :style {:width "5em"}
[:name :id]]) :field field
:type "typeahead-v3" :size 3
:field field :spec ::entity/dom}]])]])
:event change-event
:subscription data}])]
[:h2.subtitle "Address"] (if is-admin?
[address-field {:field [:address] [form-builder/section {:title "Expense Accounts"}
:event change-event [default-with-overrides {:data data
:subscription data}] :mandatory? true
[:h2.subtitle "Contact"] :default-key :default-account
[horizontal-field :override-key :account-overrides}
[:label.label "Primary"] (fn [field client]
[:div.control.has-icons-left [form-builder/raw-field
[bind-field [search-backed-typeahead {:search-query (fn [i]
[:input.input.is-expanded {:type "text" [:search_account
:field [:primary-contact :name] {:query i
:spec ::contact/name :client-id (:id client)}
:event change-event [:name :id]])
:subscription data}]] :type "typeahead-v3"
[:span.icon.is-small.is-left :style {:width "15em"}
[:i.fa.fa-user]]] :field field}]])]]
[:div.control.has-icons-left [form-builder/horizontal-field
[:span.icon.is-small.is-left "Expense Account"
[:i.fa.fa-envelope]] [search-backed-typeahead {:search-query (fn [i]
[bind-field [:search_account
[:input.input {:type "email" {:query i}
:field [:primary-contact :email] [:name :id]])
:spec ::contact/email :type "typeahead-v3"
:event change-event :field :default-account}]])
:subscription data}]]]
[:div.control.has-icons-left [form-builder/with-scope {:scope [:address ]}
[bind-field [form-builder/section {:title "Address"}
[:input.input {:type "phone" [address2-field]]]
:field [:primary-contact :phone]
:spec ::contact/phone
:event change-event
:subscription data}]]
[:span.icon.is-small.is-left
[:i.fa.fa-phone]]]]
[horizontal-field
[:label.label "Secondary"]
[:div.control.has-icons-left
[bind-field
[:input.input.is-expanded {:type "text"
:field [:secondary-contact :name]
:spec ::contact/name
:event change-event
:subscription data}]]
[:span.icon.is-small.is-left
[:i.fa.fa-user]]]
[:div.control.has-icons-left
[:span.icon.is-small.is-left
[:i.fa.fa-envelope]]
[bind-field
[:input.input {:type "email"
:field [:secondary-contact :email]
:spec ::contact/email
:event change-event
:subscription data}]]]
[:div.control.has-icons-left
[bind-field
[:input.input {:type "phone"
:field [:secondary-contact :phone]
:spec ::contact/phone
:event change-event
:subscription data}]]
[:span.icon.is-small.is-left
[:i.fa.fa-phone]]]]
[horizontal-field
[:label.label "Invoice Reminders"]
[:div.control
[:label.radio
[bind-field
[:input {:type "radio"
:name "schedule"
:value "Weekly"
:field :invoice-reminder-schedule
:spec ::entity/invoice-reminder-schedule
:event change-event
:subscription data}]]
" Send weekly"]
[:label.radio [form-builder/section {:title "Contact"}
[bind-field [form-builder/horizontal-control
[:input {:type "radio" "Primary"
:name "schedule" [:div.control.has-icons-left
:value "Never" [form-builder/raw-field
:field :invoice-reminder-schedule [:input.input.is-expanded {:type "text"
:spec ::entity/invoice-reminder-schedule :field [:primary-contact :name]
:event change-event :spec ::contact/name}]]
:subscription data}]] [:span.icon.is-small.is-left
" Never"]]] [:i.fa.fa-user]]]
[:h2.subtitle "Legal Entity"] [:div.control.has-icons-left
[horizontal-field [:span.icon.is-small.is-left
[:label.label "Name"] [:i.fa.fa-envelope]]
[:div.control [form-builder/raw-field
[bind-field [:input.input {:type "email"
[:input.input {:type "text" :field [:primary-contact :email]
:placeholder "First Name" :spec ::contact/email}]]]
:field [:legal-entity-first-name]
:spec ::contact/name
:event change-event
:subscription data}]]]
[:div.control [:div.control.has-icons-left
[bind-field [form-builder/raw-field
[:input.input {:type "text" [:input.input {:type "phone"
:placeholder "Middle Name" :field [:primary-contact :phone]
:field [:legal-entity-middle-name] :spec ::contact/phone}]]
:spec ::contact/name [:span.icon.is-small.is-left
:event change-event [:i.fa.fa-phone]]]]
:subscription data}]]] [form-builder/horizontal-control
"Secondary"
[:div.control.has-icons-left
[form-builder/raw-field
[:input.input.is-expanded {:type "text"
:field [:secondary-contact :name]
:spec ::contact/name}]]
[:span.icon.is-small.is-left
[:i.fa.fa-user]]]
[:div.control.has-icons-left
[:span.icon.is-small.is-left
[:i.fa.fa-envelope]]
[form-builder/raw-field
[:input.input {:type "email"
:field [:secondary-contact :email]
:spec ::contact/email}]]]
[:div.control.has-icons-left
[form-builder/raw-field
[:input.input {:type "phone"
:field [:secondary-contact :phone]
:spec ::contact/phone}]]
[:span.icon.is-small.is-left
[:i.fa.fa-phone]]]]]
[:div.control
[bind-field
[:input.input {:type "text"
:placeholder "Last Name"
:field [:legal-entity-last-name]
:spec ::contact/name
:event change-event
:subscription data}]]]]
[horizontal-field
[:label.label "TIN"]
[:div.control
[bind-field
[:input.input {:type "text"
:placeholder "SSN or EIN"
:field [:legal-entity-tin]
:size "12"
:spec ::contact/name
:event change-event
:subscription data}]]]
[:div.control (when is-admin?
[:div.select [form-builder/section {:title "Legal Entity"}
[bind-field [form-builder/horizontal-control
[:select {:type "select" "Name"
:field [:legal-entity-tin-type] [:div.control
:event change-event [form-builder/raw-field
:subscription data} [:input.input {:type "text"
[:option {:value nil} ""] :placeholder "First Name"
[:option {:value "ein"} "EIN"] :field [:legal-entity-first-name]
[:option {:value "ssn"} "SSN"]]]]]] :spec ::contact/name}]]]
[horizontal-field [:div.control
[:label.label "1099 Type"] [form-builder/raw-field
[:div.control [:input.input {:type "text"
[:div.select :placeholder "Middle Name"
[bind-field :field [:legal-entity-middle-name]
[:select {:type "select" :spec ::contact/name}]]]
:field [:legal-entity-1099-type]
:event change-event [:div.control
:subscription data} [form-builder/raw-field
[:option {:value nil} ""] [:input.input {:type "text"
[:option {:value "none"} "Don't 1099"] :placeholder "Last Name"
[:option {:value "misc"} "Misc"] :field [:legal-entity-last-name]
[:option {:value "landlord"} "Landlord"]]]]]]])) :spec ::contact/name}]]]]
[form-builder/horizontal-control
"TIN"
[:div.control
[form-builder/raw-field
[:input.input {:type "text"
:placeholder "SSN or EIN"
:field [:legal-entity-tin]
:size "12"
:spec ::contact/name}]]]
[:div.control
[:div.select
[form-builder/raw-field
[:select {:type "select"
:field [:legal-entity-tin-type]}
[:option {:value nil} ""]
[:option {:value "ein"} "EIN"]
[:option {:value "ssn"} "SSN"]]]]]]
[form-builder/horizontal-control
"1099 Type"
[:div.control
[:div.select
[form-builder/raw-field
[:select {:type "select"
:field [:legal-entity-1099-type]}
[:option {:value nil} ""]
[:option {:value "none"} "Don't 1099"]
[:option {:value "misc"} "Misc"]
[:option {:value "landlord"} "Landlord"]]]]]]])]]))
(defn vendor-dialog [ ] (defn vendor-dialog [ ]
(let [{:keys [data]} @(re-frame/subscribe [::forms/form ::vendor-form]) (let [{:keys [data]} @(re-frame/subscribe [::forms/form ::vendor-form])]
change-event [::changed]]
[:div [:div
[form-content {:data data :change-event change-event}]])) [form-content {:data data}]]))
(re-frame/reg-event-fx (re-frame/reg-event-fx
::vendor-selected ::vendor-selected
@@ -479,24 +428,21 @@
true true
false))) false)))
(def select-vendor-form (forms/vertical-form {:submit-event [::vendor-selected]
:change-event [::forms/change ::select-vendor-form]
:can-submit [::can-submit-select-vendor-form]
:id ::select-vendor-form}))
(defn select-vendor-form-content [] (defn select-vendor-form-content []
(let [_ @(re-frame/subscribe [::forms/form ::select-vendor-form]) [form-builder/builder {:submit-event [::vendor-selected]
{:keys [form-inline field]} select-vendor-form] :can-submit [::can-submit-select-vendor-form]
(form-inline {} :id ::select-vendor-form}
[:<> [form-builder/field
(field "Vendor to edit" "Vendor to edit"
[search-backed-typeahead {:search-query (fn [i] [search-backed-typeahead {:search-query (fn [i]
[:search_vendor [:search_vendor
{:query i} {:query i}
[:name :id]]) [:name :id]])
:type "typeahead-v3" :type "typeahead-v3"
:auto-focus true :auto-focus true
:field [:vendor]}])]))) :field [:vendor]}]]
#_[form-builder/submit-button "Save"]])
@@ -505,24 +451,24 @@
(fn [{:keys [db]} [_ vendor]] (fn [{:keys [db]} [_ vendor]]
{:db (-> db (forms/start-form ::vendor-form (-> vendor {:db (-> db (forms/start-form ::vendor-form (-> vendor
(update :account-overrides #(mapv (update :account-overrides #(mapv
(fn [ao] (fn [ao]
{:id (:id ao) {:id (:id ao)
:client (:client ao) :client (:client ao)
:override (:account ao)}) :override (:account ao)})
%)) %))
(update :schedule-payment-dom #(mapv (update :schedule-payment-dom #(mapv
(fn [spdom] (fn [spdom]
{:id (:id spdom) {:id (:id spdom)
:client (:client spdom) :client (:client spdom)
:override (:dom spdom)}) :override (:dom spdom)})
%)) %))
(update :terms-overrides #(mapv (update :terms-overrides #(mapv
(fn [to] (fn [to]
{:id (:id to) {:id (:id to)
:client (:client to) :client (:client to)
:override (:terms to)}) :override (:terms to)})
%)) %))
(update :automatically-paid-when-due #(mapv identity %)) (update :automatically-paid-when-due #(mapv identity %))
(update :hidden #(if (nil? %) (update :hidden #(if (nil? %)
false false