149 lines
7.4 KiB
Clojure
149 lines
7.4 KiB
Clojure
(ns auto-ap.views.components.expense-accounts-dialog
|
|
(:require [re-frame.core :as re-frame]
|
|
[reagent.core :as r]
|
|
[clojure.string :as str]
|
|
[clojure.spec.alpha :as s]
|
|
[cljs-time.core :as c]
|
|
[goog.string :as gstring]
|
|
[auto-ap.subs :as subs]
|
|
[auto-ap.entities.clients :as client]
|
|
[auto-ap.entities.invoice :as invoice]
|
|
[auto-ap.entities.vendors :as vendor]
|
|
[auto-ap.expense-accounts :as expense-accounts]
|
|
[auto-ap.entities.invoices-expense-accounts :as invoices-expense-accounts]
|
|
[auto-ap.views.components.modal :refer [modal action-modal]]
|
|
[auto-ap.views.utils :refer [dispatch-event bind-field horizontal-field date->str str->date pretty standard]]
|
|
[auto-ap.utils :refer [by replace-if]]
|
|
[auto-ap.views.components.typeahead :refer [typeahead]]
|
|
[auto-ap.events :as events]))
|
|
|
|
(re-frame/reg-sub
|
|
::change-expense-accounts
|
|
(fn [db]
|
|
(-> db ::change-expense-accounts)))
|
|
|
|
(re-frame/reg-event-fx
|
|
::change-expense-accounts
|
|
(fn [{:keys [db]} [_ i]]
|
|
{:dispatch [::events/modal-status ::change-expense-accounts {:visible? true}]
|
|
:db (assoc-in db [::change-expense-accounts :invoice] i)}))
|
|
|
|
(re-frame/reg-event-fx
|
|
::change-expense-accounts-saving
|
|
(fn [{:keys [db]} [_ on-success id ]]
|
|
(let [{:keys [id expense-accounts]} (get-in db [::change-expense-accounts :invoice])]
|
|
{:graphql
|
|
{:token (-> db :user)
|
|
:query-obj {:venia/operation {:operation/type :mutation
|
|
:operation/name "EditExpenseAccounts"}
|
|
|
|
:venia/queries [{:query/data [:edit-expense-accounts
|
|
{:invoice-id id
|
|
:expense-accounts (map (fn [ea] {:id (:id ea)
|
|
:amount (:amount ea)
|
|
:location (:location ea)
|
|
:expense-account-id (:expense-account-id ea)})
|
|
expense-accounts)}
|
|
[:id :total :outstanding-balance :invoice-number :date
|
|
[:vendor [:name :id]]
|
|
[:expense_accounts [:amount :id :location :expense_account_id
|
|
[:expense_account [:id :name [:parent [:id :name]]]]]]
|
|
[:client [:name :id :locations]]
|
|
[:payments [:amount [:payment [:amount :s3_url :check_number ]]]]
|
|
]]}]}
|
|
:on-success on-success}})))
|
|
|
|
|
|
|
|
|
|
(re-frame/reg-event-db
|
|
::add-expense-account-split
|
|
(fn [db _]
|
|
(let [{{{:keys [locations]} :client} :invoice} @(re-frame/subscribe [::change-expense-accounts])]
|
|
(update-in db [::change-expense-accounts :invoice :expense-accounts]
|
|
conj {:amount 0 :expense-account-id nil :location (first locations)}))))
|
|
|
|
(re-frame/reg-event-db
|
|
::remove-expense-account-split
|
|
(fn [db [_ index]]
|
|
(update-in db [::change-expense-accounts :invoice :expense-accounts]
|
|
(fn [expense-accounts]
|
|
(vec (concat (take index expense-accounts)
|
|
(drop (inc index) expense-accounts)))))))
|
|
|
|
|
|
(defn change-expense-accounts-modal [{:keys [updated-event]}]
|
|
(let [{{:keys [expense-accounts total ] :or {expense-accounts [] total 0} {:keys [locations]} :client} :invoice :as data} @(re-frame/subscribe [::change-expense-accounts])
|
|
multi-location? (> (count locations) 1)
|
|
change-event [::events/change-form [::change-expense-accounts]]
|
|
chooseable-expense-accounts @(re-frame/subscribe [::subs/chooseable-expense-accounts])
|
|
expense-accounts-total (->> expense-accounts
|
|
(map :amount)
|
|
(map js/parseFloat)
|
|
(map #(or % 0))
|
|
(reduce + 0))
|
|
does-add-up? (< (Math/abs (- expense-accounts-total (js/parseFloat total))) 0.01)]
|
|
[action-modal {:id ::change-expense-accounts
|
|
:title "Change expense accounts"
|
|
:action-text "Save"
|
|
:save-event [::change-expense-accounts-saving updated-event]
|
|
:can-submit? (and does-add-up?
|
|
(s/valid? (s/* ::invoices-expense-accounts/invoices-expense-account) expense-accounts))}
|
|
|
|
[:div
|
|
[:a.button.is-primary {:on-click (dispatch-event [::add-expense-account-split])} "Add split"]]
|
|
[:table.table
|
|
[:thead
|
|
[:tr
|
|
[:th {:style {:width "500px"}} "Expense Account"]
|
|
(when multi-location?
|
|
[:th {:style {:width "200px"}} "Location"])
|
|
[:th {:style {:width "300px"}} "Amount"]
|
|
[:th {:style {:width "5em"}}]]]
|
|
[:tbody
|
|
(for [[expense-account index] (map vector expense-accounts (range))]
|
|
^{:key index}
|
|
[:tr
|
|
[:td.expandable [:div.control
|
|
[bind-field
|
|
[typeahead {:matches (map (fn [x] [(:id x) (str (:id x) " - " (:name x))]) chooseable-expense-accounts)
|
|
:type "typeahead"
|
|
:field [:invoice :expense-accounts index :expense-account-id]
|
|
:event change-event
|
|
:spec ::invoice/vendor-id
|
|
:subscription data}]]]]
|
|
|
|
(when multi-location?
|
|
[:td
|
|
(if-let [forced-location (-> expense-account :expense-account-id expense-accounts/expense-accounts :location)]
|
|
[:div.select
|
|
[:select {:disabled "disabled" :value forced-location} [:option {:value forced-location} forced-location]]]
|
|
[:div.select
|
|
[bind-field
|
|
[:select {:type "select"
|
|
:field [:invoice :expense-accounts index :location]
|
|
:spec (set locations)
|
|
:event change-event
|
|
:subscription data}
|
|
(map (fn [l] ^{:key l} [:option {:value l} l]) locations)]]])])
|
|
|
|
[:td
|
|
[:div.control
|
|
[:div.field.has-addons.is-extended
|
|
[:p.control [:a.button.is-static "$"]]
|
|
[:p.control
|
|
[bind-field
|
|
[:input.input {:type "number"
|
|
:field [:invoice :expense-accounts index :amount]
|
|
:event change-event
|
|
:subscription data
|
|
:value (get-in data [:invoice :expense-accounts index :amount])
|
|
|
|
:max (:total data)
|
|
:step "0.01"}]]]]]]
|
|
[:td [:a.button {:on-click (dispatch-event [::remove-expense-account-split index])} [:i.fa.fa-times]]]]
|
|
)
|
|
[:tr
|
|
[:th "TOTAL"]
|
|
[:th (str (gstring/format "$%.2f" expense-accounts-total ) " (" (gstring/format "$%.2f" total ) ")" )]]]]]))
|