(ns auto-ap.views.pages.transactions.bulk-updates (:require [auto-ap.forms :as forms] [auto-ap.status :as status] [auto-ap.subs :as subs] [auto-ap.views.components.expense-accounts-field :as expense-accounts-field :refer [expense-accounts-field-v2]] [auto-ap.views.components.modal :as modal] [auto-ap.views.pages.data-page :as data-page] [auto-ap.views.pages.transactions.common :refer [data-params->query-params]] [auto-ap.views.utils :refer [dispatch-event with-user]] [clojure.string :as str] [re-frame.core :as re-frame] [reagent.core :as r] [vimsical.re-frame.fx.track :as track] [auto-ap.events :as events] [vimsical.re-frame.cofx.inject :as inject] [auto-ap.forms.builder :as form-builder] [malli.core :as m] [auto-ap.schema :as schema] [auto-ap.views.components :as com])) (re-frame/reg-sub ::can-submit :<- [::forms/form ::form] (fn [{ {:keys []} :data}] true)) (re-frame/reg-event-fx ::coded (fn [_ [_ _ _]] {:dispatch-n [[::modal/modal-closed] [:auto-ap.views.pages.transactions/params-change @(re-frame/subscribe [::data-page/params :auto-ap.views.pages.transactions/page])]]})) (re-frame/reg-event-fx ::code-selected [with-user (forms/in-form ::form) (re-frame/inject-cofx ::inject/sub [::subs/client])] (fn [{:keys [user db] ::subs/keys [client]} [_ checked]] (let [checked-params (get checked "header") specific-transactions (map :id (vals (dissoc checked "header"))) data (:data db)] {:graphql {:token user :owns-state {:single ::form} :query-obj {:venia/operation {:operation/type :mutation :operation/name "BulkCodeTransactions"} :venia/queries [[:bulk-code-transactions {:filters (some-> checked-params data-params->query-params) :client_id (:id client) :ids specific-transactions :vendor (:id (:vendor data)) :approval-status (:transaction-approval-status data) :accounts (map #(-> % (update :id (fn [i] (if (some-> i (str/starts-with? "new-")) nil i))) (assoc :percentage (/ (get-in % [:amount-percentage]) 100 )) (assoc :account-id (get-in % [:account :id])) (select-keys [:percentage :id :location :account-id])) (:accounts data))} [:message] ]]} :on-success (fn [result] [::coded (:message result) checked-params ])}}))) (re-frame/reg-event-db ::changed (forms/change-handler ::form (fn [data field value] (cond (and (= [:vendor-preferences] field) value) [[:accounts] (expense-accounts-field/default-account (:accounts data) (:default-account value) (:total data) [])] :else [])))) (re-frame/reg-event-fx ::changed-vendor [(forms/in-form ::form)] (fn [{{{:keys [client]} :data} :db} [_ vendor]] (when (and (:id client) (:id vendor)) {:dispatch [::events/vendor-preferences-requested {:client-id (:id client) :vendor-id (:id vendor) :on-success [::changed [:vendor-preferences]] :on-failure [:hello]}]}))) (re-frame/reg-event-fx ::mounted (fn [] {::track/register {:id ::vendor-change :subscription [::forms/field ::form [:vendor]] :event-fn (fn [v] [::changed-vendor v])}})) (re-frame/reg-event-fx ::unmounted (fn [] {::track/dispose {:id ::vendor-change}})) (def bulk-update-schema (m/schema [:map [:vendor schema/reference]])) (defn form-content [_] (let [{:keys [data]} @(re-frame/subscribe [::forms/form ::form])] [form-builder/builder {:submit-event [::code-selected] :change-event [::changed] :can-submit [::can-submit] :id ::form} [form-builder/field-v2 {:field :vendor} "Vendor" [com/search-backed-typeahead {:search-query (fn [i] [:search_vendor {:query i} [:name :id]]) :auto-focus true}]] [form-builder/field-v2 {:field [:transaction-approval-status]} "Approval Status" [com/button-radio-input {:options [[:unapproved "Unapproved"] [:requires-feedback "Client Review"] [:approved "Approved"] [:excluded "Excluded from Ledger"]]}]] [form-builder/raw-field-v2 {:field :accounts} [expense-accounts-field-v2 {:descriptor "account asssignment" :percentage-only? true :client (:client data) :locations (into ["Shared"] @(re-frame/subscribe [::subs/locations-for-client (:id (:client data))])) :max 100}]]])) (defn form [_] (r/create-class {:display-name "transaction-bulk-update-form" :component-did-mount #(re-frame/dispatch [::mounted]) :component-will-unmount #(re-frame/dispatch [::unmounted]) :reagent-render (fn [p] [form-content p])})) (re-frame/reg-event-fx ::code-requested (fn [{:keys [db]} [_ checked params]] (let [to-delete (if (get checked "header") [:b.strong.has-text-danger "all visible transactions"] (str (count checked) " transactions"))] {:dispatch [::modal/modal-requested {:title "Confirmation" :body [:div "Please fill in the details on how to code " to-delete ":" [form ]] :cancel? true :confirm {:value "Code" :class "is-danger" :status-from [::status/single ::form] :on-click (dispatch-event [::code-selected checked] )} :close-event [::status/completed ::code-selected]}] :db (-> db (forms/start-form ::form {:accounts [] :client @(re-frame/subscribe [::subs/client (:client-id params)])}))})))