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