(ns auto-ap.events (:require [re-frame.core :as re-frame] [auto-ap.db :as db] [auto-ap.subs :as subs] [auto-ap.routes :as routes] [auto-ap.effects :as effects] [auto-ap.utils :refer [by]] [venia.core :as v] [bidi.bidi :as bidi] [cemerick.url :refer [url]] [goog.crypt.base64 :as b64] [clojure.string :as str])) (defn jwt->data [token] (js->clj (.parse js/JSON (b64/decodeString (second (str/split token #"\." )))))) (re-frame/reg-event-fx ::initialize-db (fn [{:keys [db]} [_ token]] (let [handler (:handler (bidi/match-route routes/routes (.. js/window -location -pathname)))] (prn (and token (get (jwt->data token) "user/role"))) (cond (and (not= :login handler) (not token)) {:redirect "/login" :db (assoc db/default-db :active-page :login :last-client-id (.getItem js/localStorage "last-client-id") :user token)} (and token (= "none" (or (get (jwt->data token) "role") (get (jwt->data token) "user/role")) )) {:redirect "/needs-activation" :db (assoc db/default-db :active-page :needs-activation :last-client-id (.getItem js/localStorage "last-client-id") :user token)} :else {:db (assoc db/default-db :active-page handler :last-client-id (.getItem js/localStorage "last-client-id") :query-params (->> (:query (url (.-location js/window))) (map (fn [[k v]] [(keyword k) v])) (into {})) :user token) :graphql {:token token :query-obj {:venia/queries [[:client [:id :name :code :email :matches :locations [:location-matches [:location :match]] [:bank-accounts [:id :code :number :bank-name :bank-code :check-number :name :routing :type :sort-order :visible :yodlee-account-id :locations] ] [:address [:street1 :street2 :city :state :zip]]]] [:vendor [:id :name :hidden [:default-account [:name :id :location]] [:primary-contact [:name :phone :email :id]] [:secondary-contact [:id :name :phone :email]] :print-as :invoice-reminder-schedule :code]] [:accounts [:numeric-code :location :name :type :account_set :id]]]} :on-success [::received-initial]}})))) (def vendor-query [:id :name :hidden [:default-account [:name :id :location]] [:primary-contact [:name :phone :email :id]] [:secondary-contact [:id :name :phone :email]] :print-as :invoice-reminder-schedule :code [:address [:street1 :street2 :city :state :zip]]]) (re-frame/reg-event-db ::toggle-menu (fn [db [_ which]] (update-in db [:menu which :active?] #(not %)))) (re-frame/reg-event-fx ::logged-in (fn [{:keys [db]} [_ token user]] {:graphql {:token token :query-obj {:venia/queries [[:client [:id :name :code :matches :locations [:location-matches [:location :match]] [:address [:street1 :street2 :city :state :zip]] [:bank-accounts [:id :code :number :bank-name :bank-code :check-number :name :routing :type :sort-order :visible :yodlee-account-id :locations] ]]] [:vendor [:id :name :hidden [:default-account [:name :id :location]] [:primary-contact [:name :phone :email :id]] [:secondary-contact [:id :name :phone :email]] :print-as :invoice-reminder-schedule :code]] [:accounts [:numeric-code :name :location :type :account_set :id]]]} :on-success [::received-initial]} :db (assoc db :user (assoc user :token token))})) (re-frame/reg-event-db ::received-initial (fn [db [_ {accounts :accounts clients :client vendors :vendor :as x}]] (-> db (assoc :clients (by :id clients) ) (assoc :vendors (by :id vendors) ) (assoc :accounts accounts ) (assoc :client (or (when (= 1 (count clients)) (->> clients first :id )) (->> clients (map :id) (filter #(= % (:last-client-id db))) first)))))) (re-frame/reg-event-db ::swap-client (fn [db [_ client]] (.setItem js/localStorage "last-client-id" (:id client)) (assoc db :client (:id client)))) (re-frame/reg-event-db ::change-form (fn [db [_ location field value]] (if value (assoc-in db (into location field) value) (update-in db (into location (butlast field)) dissoc (last field))))) (re-frame/reg-event-db ::modal-status (fn [db [_ id state]] (println "changing modal status" id "to") (-> db (update-in [:modal-state id] #(merge % state)) #_(dissoc :auto-ap.forms/forms) ))) (re-frame/reg-event-db ::modal-failed (fn [db [_ id message]] (-> db (assoc-in [:modal-state id :saving?] false) (assoc-in [:modal-state id :error-message] message)))) (re-frame/reg-event-db ::modal-completed (fn [db [_ id state]] (-> db (update-in [:modal-state] #(dissoc % id)) (update :auto-ap.forms/forms dissoc id)))) (re-frame/reg-event-fx ::set-active-page (fn [{:keys [db]} [_ handler params]] (if (and (not= :login handler) (not (:user db))) {:redirect "/login" :db (assoc db :active-page :login :page-failure nil :auto-ap.forms/forms nil)} {:db (assoc db :active-page handler :page-failure nil :query-params params :auto-ap.forms/forms nil)}))) (re-frame/reg-event-db ::imported-invoices (fn [db [_ new-invoices]] (assoc-in db [:invoices :pending] new-invoices))) (re-frame/reg-event-fx ::view-pending-invoices (fn [cofx []] {:db (assoc-in (:db cofx) [:status :loading] true) :graphql {:token (-> cofx :db :user) :query-obj {:venia/queries [[:invoice {:imported false :client_id (:id @(re-frame/subscribe [::subs/client]))} [:id :total :invoice-number :date [:vendor [:name :id]] [:client [:name :id]]]]]} :on-success [::received-invoices :pending]}})) (re-frame/reg-event-fx ::view-unpaid-invoices (fn [cofx []] {:db (assoc-in (:db cofx) [:status :loading] true) :graphql {:token (-> cofx :db :user) :query-obj {:venia/queries [[:invoice {:imported true :client_id (:id @(re-frame/subscribe [::subs/client]))} [:id :total :invoice-number :date [:vendor [:name :id]] [:client [:name :id]]]]]} :on-success [::received-invoices :unpaid]}})) (re-frame/reg-event-db ::submitted-new-invoice (fn [db [_ invoice]] (assoc db :new-invoice {}))) (re-frame/reg-event-fx ::logout (fn [{:keys [db]} [_ logout-reason]] {:db (assoc db :user nil :menu {:client {:active? false} :account {:active? false}} :logout-reason logout-reason) :redirect (bidi/path-for routes/routes :login) :set-local-storage ["jwt" nil]})) (re-frame/reg-event-fx ::submit-new-invoice (fn [{:keys [db]} [_ invoice]] {:http {:method :post :token (-> db :user) :uri "/api/invoices" :body (pr-str {:rows [(assoc invoice :imported true)]}) :headers {"Content-Type" "application/edn"} :on-success [::submitted-new-invoice]} :db (assoc-in db [:new-invoice :loading?] true)})) (re-frame/reg-event-db ::received-invoices (fn [db [_ type result]] (let [new-invoices (if (:invoice result) (:invoice result) result)] (-> db (assoc-in [:invoices type] new-invoices) (assoc-in [:status :loading] false))))) (re-frame/reg-event-db ::change-form-state (fn [db [_ target value]] (assoc-in db target value))) (re-frame/reg-event-db ::change-nested-form-state (fn [db [_ form more value]] (update-in db form (fn [x] (assoc-in x more value))))) (re-frame/reg-event-db ::page-failed (fn [db [_ result]] (println "Page failure" result) (assoc db :page-failure result :status nil))) (re-frame/reg-event-db ::yodlee-merchants-received (fn [db [_ data]] (assoc db :yodlee-merchants (:yodlee-merchants data)))) (re-frame/reg-event-fx ::yodlee-merchants-needed (fn [{:keys [db]} _] {:graphql {:token (:user db) :query-obj {:venia/queries [[:yodlee-merchants [:name :yodlee-id :id]]]} :on-success [::yodlee-merchants-received]}}))