(ns auto-ap.views.pages.unpaid-invoices (: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.entities.companies :as company] [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.utils :refer [dispatch-event bind-field horizontal-field date->str str->date pretty standard]] [auto-ap.utils :refer [by replace-if]] [auto-ap.views.pages.check :as check] [auto-ap.views.components.invoice-table :refer [invoice-table] :as invoice-table] [auto-ap.views.components.modal :refer [modal action-modal]] [auto-ap.views.components.typeahead :refer [typeahead]] [auto-ap.subs :as subs] [auto-ap.events :as events])) (re-frame/reg-sub ::invoice-page (fn [db] (-> db ::invoice-page))) (re-frame/reg-sub ::invoice (fn [db id] (get (by :id (-> db ::invoice-page :invoices )) id))) (re-frame/reg-sub ::advanced-print-checks (fn [db] (-> db ::advanced-print-checks))) (re-frame/reg-sub ::handwrite-checks (fn [db] (-> db ::handwrite-checks))) (re-frame/reg-sub ::change-expense-accounts (fn [db] (-> db ::change-expense-accounts))) (re-frame/reg-sub ::check-results (fn [db] (-> db ::check-results))) (re-frame/reg-sub ::new-invoice (fn [db] (-> db ::new-invoice))) (re-frame/reg-sub ::edit-invoice (fn [db] (-> db ::edit-invoice))) (re-frame/reg-sub ::params (fn [db] (-> db (::params {})))) (re-frame/reg-event-fx ::params-change (fn [cofx [_ params]] {:db (-> (:db cofx) (assoc-in [:status :loading] true) (assoc-in [::params] params)) :graphql {:token (-> cofx :db :user) :query-obj (invoice-table/query (assoc params :imported true :status "unpaid")) :on-success [::received]}})) (re-frame/reg-event-db ::received (fn [db [_ data]] (-> db (assoc ::invoice-page (first (:invoice-page data))) (assoc-in [:status :loading] false)))) (re-frame/reg-event-db ::toggle-check (fn [db [_ data]] (update-in db [::invoice-page :checked] (fn [x] (let [x (or x #{})] (if (x data) (disj x data) (conj x data))))))) (re-frame/reg-event-db ::print-checks-clicked (fn [db _] (update-in db [::invoice-page :print-checks-shown?] #(not %) ))) (re-frame/reg-event-db ::advanced-print-checks (fn [db _] (let [{:keys [checked invoices]} (get-in db [::invoice-page])] (-> db (update-in [::invoice-page :print-checks-shown?] #(not %) ) (assoc-in [::advanced-print-checks] {:shown? true :bank-account-id (:id (first (:bank-accounts @(re-frame/subscribe [::subs/company])))) :invoices (->> invoices (filter (comp checked :id)) (map #(assoc % :amount (:outstanding-balance %))))} ))))) (re-frame/reg-event-fx ::handwrite-checks (fn [{:keys [db]} _] (let [{:keys [checked invoices]} (get-in db [::invoice-page]) invoice (->> invoices (filter (comp checked :id)) first) ] {:dispatch [::events/modal-status ::handwrite-checks {:visible? true}] :db (-> db (update-in [::invoice-page :print-checks-shown?] #(not %) ) (assoc-in [::handwrite-checks] {:bank-account-id (:id (first (:bank-accounts @(re-frame/subscribe [::subs/company])))) :amount (:outstanding-balance invoice) :invoice invoice } ))}))) (re-frame/reg-event-db ::cancel-advanced-print (fn [db _] (assoc-in db [::advanced-print-checks :shown?] false ))) (re-frame/reg-event-db ::close-check-results (fn [db _] (assoc-in db [::check-results :shown?] false ))) (re-frame/reg-event-db ::edit-payment-bank-account (fn [db [_ f v]] (assoc-in db [::advanced-print-checks :bank-account-id] v))) (re-frame/reg-event-db ::edit-payment (fn [db [_ which f v]] (update-in db [::advanced-print-checks :invoices] (fn [is] (for [i is] (if (= which (:id i)) (assoc-in i f v) i)))))) (defn print-checks-query [invoice-payments bank-account-id type company-id] {:venia/operation {:operation/type :mutation :operation/name "PrintChecks"} :venia/queries [[:print-checks {:invoice_payments invoice-payments :type type :bank_account_id bank-account-id :company_id company-id} [[:invoices [:id :outstanding-balance [:checks [:amount [:check [:amount :s3_url :check_number ]]]]]] :pdf_url]]]}) (re-frame/reg-event-fx ::print-checks (fn [{:keys [db]} [_ bank-account-id type]] (let [invoice-amounts (by :id :outstanding-balance (get-in db [::invoice-page :invoices]))] {:db (-> db (assoc-in [::invoice-page :print-checks-shown?] false ) (assoc-in [::invoice-page :print-checks-loading?] true )) :graphql {:token (-> db :user) :query-obj (print-checks-query (map (fn [id] {:invoice-id id :amount (invoice-amounts id)}) (get-in db [::invoice-page :checked])) bank-account-id type (:company db)) :on-success [::checks-created]}}))) (re-frame/reg-event-fx ::advanced-print-checks-submitted (fn [{:keys [db]} [_ bank-account-id]] (let [invoice-amounts (by :id (comp js/parseFloat :amount) (get-in db [::advanced-print-checks :invoices])) bank-account-id (get-in db [::advanced-print-checks :bank-account-id]) type (->> @(re-frame/subscribe [::subs/company]) :bank-accounts (filter #(= bank-account-id (:id %))) first :type)] {:db (-> db (assoc-in [::advanced-print-checks :printing?] true )) :graphql {:token (-> db :user) :query-obj (print-checks-query (map (fn [x] {:invoice-id (:id x) :amount (invoice-amounts (:id x))}) (get-in db [::advanced-print-checks :invoices])) bank-account-id (or type "check") (:company db)) :on-success [::checks-created]}}))) (re-frame/reg-event-fx ::checks-created (fn [{:keys [db]} [_ data]] (let [{{:keys [pdf-url invoices]} :print-checks} data invoices-by-id (by :id invoices) ] { :db (-> db (update-in [::invoice-page :invoices] (fn [invoices] (map (fn [i] (merge i (invoices-by-id (:id i)))) invoices))) (assoc-in [::invoice-page :checked] nil) (assoc-in [::invoice-page :print-checks-loading?] false) (assoc-in [::advanced-print-checks :printing?] false) (assoc-in [::advanced-print-checks :shown?] false) (assoc-in [::check-results :shown?] true) (assoc-in [::check-results :pdf-url] pdf-url) )}))) (re-frame/reg-event-fx ::invalidated (fn [cofx [_ params]] {:dispatch [::params-change @(re-frame/subscribe [::params])]})) (re-frame/reg-event-fx ::new-invoice (fn [{:keys [db]} _] {:dispatch [::events/modal-status ::new-invoice {:visible? true}] :db (assoc-in db [::new-invoice] {:company-id (:id @(re-frame/subscribe [::subs/company])) :date (date->str (c/now) standard) :location (first (:locations @(re-frame/subscribe [::subs/company])))})})) (re-frame/reg-event-fx ::edit-invoice (fn [{:keys [db]} [_ which]] (let [edit-invoice (update which :date #(date->str % standard)) edit-invoice (assoc edit-invoice :original edit-invoice)] {:dispatch [::events/modal-status ::edit-invoice {:visible? true}] :db (assoc-in db [::edit-invoice] edit-invoice)}))) (re-frame/reg-event-fx ::create-invoice (fn [{:keys [db]} _] (let [new-invoice @(re-frame/subscribe [::new-invoice])] {:graphql {:token (-> db :user) :query-obj {:venia/operation {:operation/type :mutation :operation/name "AddInvoice"} :venia/queries [{:query/data [:add-invoice {:invoice new-invoice} [:id :total :outstanding-balance :date :invoice-number [:company [:id :name :locations]] [:vendor [:id :name]] [:expense_accounts [:amount :id :expense_account_id :location [:expense_account [:id :name [:parent [:id :name]]]]]] ]]}]} :on-success [::invoice-created] :on-error [::invoice-create-failed]}}))) (re-frame/reg-event-fx ::edit-invoice-save (fn [{:keys [db]} _] (let [{:keys [date total invoice-number id]} @(re-frame/subscribe [::edit-invoice])] {:graphql {:token (-> db :user) :query-obj {:venia/operation {:operation/type :mutation :operation/name "EditInvoice"} :venia/queries [{:query/data [:edit-invoice {:invoice {:id id :invoice-number invoice-number :date date :total total}} [:id :total :outstanding-balance :date :invoice-number [:company [:id :name :locations]] [:vendor [:id :name]] [:expense_accounts [:amount :id :expense_account_id :location [:expense_account [:id :name [:parent [:id :name]]]]]]]]}]} :on-success [::invoice-edited] :on-error [::invoice-edit-failed]}}))) (re-frame/reg-event-fx ::void-invoice (fn [{:keys [db]} [_ {id :id}]] {:graphql {:token (-> db :user) :query-obj {:venia/operation {:operation/type :mutation :operation/name "VoidInvoice"} :venia/queries [{:query/data [:void-invoice {:invoice-id id} [:id :total :outstanding-balance :date :invoice-number [:company [:id :name :locations]] [:vendor [:id :name]] [:expense_accounts [:amount :id :expense_account_id :location [:expense_account [:id :name [:parent [:id :name]]]]]]]]}]} :on-success [::invoice-voided]}})) (re-frame/reg-event-fx ::handwrite-checks-save (fn [{:keys [db]} _] (let [{:keys [date invoice amount check-number bank-account-id]} @(re-frame/subscribe [::handwrite-checks])] {:graphql {:token (-> db :user) :query-obj {:venia/operation {:operation/type :mutation :operation/name "AddHandwrittenCheck"} :venia/queries [{:query/data [:add-handwritten-check {:date date :amount amount :check-number check-number :bank-account-id bank-account-id :invoice_id (:id invoice) } [[:invoices [:id :outstanding-balance [:checks [:amount [:check [:amount :s3_url :check_number ]]]]]]]]}]} :on-success [::handwrite-checks-succeeded]}}))) (re-frame/reg-event-fx ::handwrite-checks-succeeded (fn [{:keys [db]} [_ {:keys [add-handwritten-check] :as result}]] (let [invoices-by-id (by :id (:invoices add-handwritten-check))] {:dispatch [::events/modal-completed ::handwrite-checks] :db (-> db (update-in [::invoice-page :invoices] (fn [invoices] (map (fn [i] (merge i (invoices-by-id (:id i)))) invoices))) (dissoc ::handwrite-checks))}))) (re-frame/reg-event-fx ::invoice-create-failed (fn [{:keys [db]} [_ data]] {:dispatch [::events/modal-failed ::new-invoice (:message data)]})) (re-frame/reg-event-fx ::invoice-created (fn [{:keys [db]} [_ {:keys [add-invoice]}]] {:dispatch [::events/modal-completed ::new-invoice] :db (-> db (update-in [::invoice-page :invoices] (fn [is] (into [(assoc add-invoice :class "live-added")] is))) (dissoc ::new-invoice))})) (re-frame/reg-event-fx ::invoice-edited (fn [{:keys [db]} [_ {:keys [edit-invoice]}]] {:dispatch [::events/modal-completed ::edit-invoice] :db (-> db (update-in [::invoice-page :invoices] (fn [is] (mapv (fn [i] (if (= (:id i) (:id edit-invoice)) (assoc edit-invoice :class "live-added") i)) is))) (dissoc ::edit-invoice))})) (re-frame/reg-event-fx ::invoice-edit-failed (fn [{:keys [db]} [_ data]] {:dispatch [::events/modal-failed ::edit-invoice "That invoice already exists."]})) (re-frame/reg-event-fx ::invoice-voided (fn [{:keys [db]} [_ {:keys [void-invoice]}]] {:db (-> db (update-in [::invoice-page :invoices] (fn [is] (mapv (fn [i] (if (= (:id i) (:id void-invoice)) (assoc void-invoice :class "live-removed") i)) is))))})) (re-frame/reg-event-fx ::change-expense-accounts (fn [{:keys [db]} [_ id]] {:dispatch [::events/modal-status ::change-expense-accounts {:visible? true}] :db (assoc-in db [::change-expense-accounts :invoice] (get (by :id (get-in db [::invoice-page :invoices])) id))})) (re-frame/reg-event-fx ::change-expense-accounts-saving (fn [{:keys [db]} [_ 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]]]]]] [:company [:name :id :locations]] [:checks [:amount [:check [:amount :s3_url :check_number ]]]] ]]}]} :on-success [::expense-accounts-updated]}}))) (re-frame/reg-event-fx ::expense-accounts-updated (fn [{:keys [db]} [_ data]] (let [updated (:edit-expense-accounts data)] {:dispatch [::events/modal-completed ::change-expense-accounts] :db (-> db (update-in [::invoice-page :invoices] (fn [is] (replace-if #(= (:id %1) (:id %2)) updated is))) (dissoc ::change-expense-accounts))}))) (re-frame/reg-event-db ::add-expense-account-split (fn [db _] (let [{{{:keys [locations]} :company} :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 [] (let [{{:keys [expense-accounts total ] :or {expense-accounts [] total 0} {:keys [locations]} :company} :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? (= expense-accounts-total (js/parseFloat total))] [action-modal {:id ::change-expense-accounts :title "Change expense accounts" :action-text "Save" :save-event [::change-expense-accounts-saving] :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) (: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 ) ")" )]]]]])) (defn print-checks-modal [] (let [{:keys [checked]} @(re-frame/subscribe [::invoice-page]) {:keys [shown? invoices printing?] :as advanced-print-checks} @(re-frame/subscribe [::advanced-print-checks]) current-company @(re-frame/subscribe [::subs/company])] (when shown? [modal {:title "Print Checks" :foot [:button.button.is-primary {:on-click (dispatch-event [::advanced-print-checks-submitted]) :disabled (cond printing? "disabled" (seq (filter #(> (js/parseFloat (:amount %)) (js/parseFloat (:outstanding-balance %))) invoices)) "disabled" :else "") :class (if printing? "is-loading" "")} [:span "Print"]] :hide-event [::cancel-advanced-print]} "Print using" [:span.field [:span.select [bind-field [:select {:type "select" :field :bank-account-id :event ::edit-payment-bank-account :subscription advanced-print-checks} (for [{:keys [id number name]} (:bank-accounts current-company)] ^{:key id} [:option {:value id} name])]]]] [:table.table [:thead [:tr [:th "Vendor"] [:th "Invoice ID"] [:th {:style {"width" "10em"}} "Payment"]]] [:tbody (for [{:keys [vendor payment outstanding-balance invoice-number id] :as i} invoices] ^{:key id} [:tr [:td (:name vendor)] [:td invoice-number] [:td [:div.field.has-addons.is-extended [:p.control [:a.button.is-static "$"]] [:p.control [bind-field [:input.input {:type "number" :field :amount :event [::edit-payment id] :subscription i :value payment :max outstanding-balance :step "0.01"}]]]]]])]]]))) (defn handwrite-checks-modal [] (let [{:keys [checked]} @(re-frame/subscribe [::invoice-page]) {:keys [invoice] :as handwrite-checks} @(re-frame/subscribe [::handwrite-checks]) change-event [::events/change-form [::handwrite-checks]] current-company @(re-frame/subscribe [::subs/company])] [action-modal {:id ::handwrite-checks :title "Handwrite Check" :action-text "Save" :save-event [::handwrite-checks-save] #_#_:can-submit? (s/valid? ::invoice/invoice data)} [horizontal-field [:label.label "Pay using"] [:span.select [bind-field [:select {:type "select" :field :bank-account-id :event change-event :subscription handwrite-checks} (for [{:keys [id number name]} (:bank-accounts current-company)] ^{:key id} [:option {:value id} name])]]]] [horizontal-field [:label.label "Paid amount"] [:div.field.has-addons.is-extended [:p.control [:a.button.is-static "$"]] [:p.control [bind-field [:input.input {:type "number" :field [:amount] :event change-event :subscription handwrite-checks :spec ::invoice/total :step "0.01"}]]]]] [horizontal-field [:label.label "Date"] [bind-field [:input.input {:type "date" :field [:date] :event change-event :spec ::invoice/date :subscription handwrite-checks}]]] [horizontal-field [:label.label "Check number"] [bind-field [:input.input {:type "number" :field [:check-number] :event change-event #_#_:spec ::check/date :subscription handwrite-checks}]]]])) (re-frame/reg-event-fx ::change-new-invoice-company (fn [{:keys [db ]} [_ location field value]] (let [first-location (-> @(re-frame/subscribe [::subs/companies-by-id]) (get-in [value :locations]) first)] {:dispatch [::events/change-form location field value] :db (-> db (assoc-in [::new-invoice :location] first-location))}))) (defn new-invoice-modal [] (let [data @(re-frame/subscribe [::new-invoice]) change-event [::events/change-form [::new-invoice]] locations (get-in @(re-frame/subscribe [::subs/companies-by-id]) [(:company-id data) :locations]) should-select-location? (and locations (> (count locations) 1))] [action-modal {:id ::new-invoice :title "New Invoice" :action-text "Create" :save-event [::create-invoice] :can-submit? (s/valid? ::invoice/invoice data)} (when-not @(re-frame/subscribe [::subs/company]) [horizontal-field [:label.label "Company"] [bind-field [typeahead {:matches (map (fn [x] [(:id x) (:name x)]) @(re-frame/subscribe [::subs/companies])) :type "typeahead" :field [:company-id] :event [::change-new-invoice-company [::new-invoice]] :spec ::invoice/company-id :subscription data}]]]) (when should-select-location? [horizontal-field [:label.label "Location"] [:div.select [bind-field [:select {:type "select" :field [:location] :spec (set locations) :event change-event :subscription data} (map (fn [l] [:option {:value l} l]) locations)]]]]) [horizontal-field [:label.label "Vendor"] [bind-field [typeahead {:matches (map (fn [x] [(:id x) (:name x)]) @(re-frame/subscribe [::subs/vendors])) :type "typeahead" :auto-focus true :field [:vendor-id] :text-field [:vendor-name] :event change-event :spec (s/nilable ::invoice/vendor-id) :subscription data}]]] [horizontal-field [:label.label "Date"] [bind-field [:input.input {:type "date" :field [:date] :event change-event :spec ::invoice/date :subscription data}]]] [horizontal-field [:label.label "Invoice #"] [bind-field [:input.input {:type "text" :field [:invoice-number] :event change-event :spec ::invoice/invoice-number :subscription data}]]] [horizontal-field [:label.label "Total"] [:div.field.has-addons.is-extended [:p.control [:a.button.is-static "$"]] [:p.control [bind-field [:input.input {:type "number" :field [:total] :event change-event :subscription data :spec ::invoice/total :step "0.01"}]]]]] ])) (defn edit-invoice-modal [] (let [data @(re-frame/subscribe [::edit-invoice]) change-event [::events/change-form [::edit-invoice]] locations (get-in @(re-frame/subscribe [::subs/companies-by-id]) [(:company-id data) :locations]) min-total (- (:total (:original data)) (:outstanding-balance (:original data))) should-select-location? (and locations (> (count locations) 1))] [action-modal {:id ::edit-invoice :title "Update Invoice" :action-text "Save" :save-event [::edit-invoice-save] :can-submit? (and #_(s/valid? ::invoice/invoice data) (>= (:total data) min-total))} [horizontal-field [:label.label "Date"] [bind-field [:input.input {:type "date" :field [:date] :event change-event :spec ::invoice/date :subscription data}]]] [horizontal-field [:label.label "Invoice #"] [bind-field [:input.input {:type "text" :field [:invoice-number] :event change-event :spec ::invoice/invoice-number :subscription data}]]] [horizontal-field [:label.label "Total"] [:div.field.has-addons.is-extended [:p.control [:a.button.is-static "$"]] [:p.control [bind-field [:input.input {:type "number" :field [:total] :event change-event :min min-total :subscription data :spec ::invoice/total :step "0.01"}]]]]] ])) (def unpaid-invoices-page (with-meta (fn [] (let [{:keys [checked print-checks-shown? print-checks-loading? advanced-print-shown?]} @(re-frame/subscribe [::invoice-page]) current-company @(re-frame/subscribe [::subs/company]) {check-results-shown? :shown? pdf-url :pdf-url} @(re-frame/subscribe [::check-results])] [:div [:h1.title "Unpaid invoices"] [:div.is-pulled-right [:button.button.is-danger {:on-click (dispatch-event [::new-invoice])} "New Invoice"] (when current-company [:div.dropdown.is-right {:class (if print-checks-shown? "is-active" "")} [:div.dropdown-trigger [:button.button.is-success {:aria-haspopup true :on-click (dispatch-event [::print-checks-clicked ]) :disabled (if (seq checked) "" "disabled") :class (if print-checks-loading? "is-loading" "")} "Pay " [:span " "] [:span.icon.is-small [:i.fa.fa-angle-down {:aria-hidden "true"}]]]] [:div.dropdown-menu {:role "menu"} [:div.dropdown-content (list (for [{:keys [id number name type]} (:bank-accounts current-company)] (if (= "cash" type) ^{:key id} [:a.dropdown-item {:on-click (dispatch-event [::print-checks id "cash"])} "With cash"] (list ^{:key (str id "-check")} [:a.dropdown-item {:on-click (dispatch-event [::print-checks id "check"])} "Print checks from " name] ^{:key (str id "-debit")} [:a.dropdown-item {:on-click (dispatch-event [::print-checks id "debit"])} "Debit from " name]))) ^{:key "advanced-divider"} [:hr.dropdown-divider] (when (= 1 (count checked)) ^{:key "handwritten"} [:a.dropdown-item {:on-click (dispatch-event [::handwrite-checks])} "Handwritten Check..."]) ^{:key "advanced"} [:a.dropdown-item {:on-click (dispatch-event [::advanced-print-checks])} "Advanced..."])]]])] [invoice-table {:id :unpaid :params (re-frame/subscribe [::params]) :invoice-page (re-frame/subscribe [::invoice-page]) :status (re-frame/subscribe [::subs/status]) :on-edit-invoice (fn [which] (re-frame/dispatch [::edit-invoice which])) :on-void-invoice (fn [which] (re-frame/dispatch [::void-invoice which])) :on-params-change (fn [params] (re-frame/dispatch [::params-change params])) :check-boxes true :checked checked :on-check-changed (fn [which] (re-frame/dispatch [::toggle-check which])) :expense-event [::change-expense-accounts]}] [print-checks-modal] [new-invoice-modal] [edit-invoice-modal] [handwrite-checks-modal] [change-expense-accounts-modal] (when check-results-shown? (if pdf-url [modal {:title "Your checks are ready!" :hide-event [::close-check-results]} [:div "Click " [:a {:href pdf-url :target "_new"} "here"] " to print them."] [:div [:em "Remember to turn off all scaling and margins."]] ] [modal {:title "Payment created!" :hide-event [::close-check-results]} [:div [:em "Your payment was created."]] ])) ])) {:component-will-mount #(re-frame/dispatch-sync [::params-change {}]) }))