diff --git a/scratch-sessions/fixing_transactions_manually_imported_incorrectl.clj b/scratch-sessions/fixing_transactions_manually_imported_incorrectl.clj index 08b33fc1..7c5636b8 100644 --- a/scratch-sessions/fixing_transactions_manually_imported_incorrectl.clj +++ b/scratch-sessions/fixing_transactions_manually_imported_incorrectl.clj @@ -117,7 +117,7 @@ '[?e2 :transaction/amount ?a2] '[?e2 :transaction/bank-account ?ba] '[(auto-ap.utils/dollars= ?a1 ?a2)] - '(not [?e2 :transaction/type])]} + '[?e2 :transaction/type]]} :args [(d/since (d/db (d/connect uri)) #inst "2020-04-01")]}) vec (map (fn [[e1 e2]] @@ -127,23 +127,27 @@ :transaction/date :transaction/id :transaction/amount :transaction/description-original :transaction/approval-status + :transaction/type {:transaction/client [:client/code]} {:transaction/bank-account [:bank-account/code]} - {:journal-entry/_original-entity ['*]}] + #_{:journal-entry/_original-entity ['*]}] e1) (d/pull (d/db (d/connect uri)) [:db/id :transaction/date :transaction/id :transaction/amount :transaction/description-original + :transaction/type :transaction/approval-status {:transaction/client [:client/code]} {:transaction/bank-account [:bank-account/code]} - {:journal-entry/_original-entity ['*]}] + #_{:journal-entry/_original-entity ['*]}] e2) ])) )) -(count matches-to-repair2) +(count (filter #(= "SCSJ" (:client/code (:transaction/client (first %)))) matches-to-repair2)) + +(sha-256 (str "2020-05-08" "-" "SCSJ-USBMAIN2974" "-" "CHECK-5075" "-" "5000.0" "-" "0" "-" "SCSJ")) (defn repair-transaction [[t-auto t-manual]] (into @@ -158,7 +162,171 @@ (defn map-new-transaction-id [[t-auto t-manual]] [[:db/add (:db/id t-manual) :transaction/id (:transaction/id t-auto)]]) -(map-new-transaction-id (first matches-to-repair)) +#_(map-new-transaction-id (first matches-to-repair)) -(doseq [t matches-to-repair] +#_(doseq [t matches-to-repair] @(d/transact (d/connect uri) (map-new-transaction-id t))) + + + +#_(comment + + (get-accounts) + +(get-provider-accounts) + +(update-provider-account 18611904) + +(get-provider-account-detail 11194727) + +(get-specific-transactions 24370737) + +[{"field" [ + {"id" "SQandA--QUESTION_1-12370368" + "value" "Oprah"} + + {"id" "SQandA--QUESTION_1-12369757" + "value" "Betelgeuse"}] }] + +(perform-additional-authentication 18611904 {"loginForm" {"row" + [{"field" [{"id" "SQandA--txtAlphaNum--1" + "value" "Christian"}]}]}}) + +{"field" [{"id" "SQandA--QUESTION_1-12370368" + "value" "Oprah"} + + {"id" "SQandA--QUESTION_1-12369757" + "value" "Betelgeuse"}]} + +(json/write-str ) + +*e + + +(get-provider-accounts-with-accounts) +(get-provider-account-detail 18611901) + + +@(d/transact (d/connect uri) (fix-transactions-without-locations "NGE1" "UC")) + +(->> (d/query {:query {:find ['?e '?tx '?yai '?d] + :in ['$] + :where ['[?e :bank-account/yodlee-account-id ?yai ?tx true] + '[?tx :db/txInstant ?d]]} + :args [(d/history (d/db (d/connect uri)))]}) + (filter (fn [[_ _ y]] + (not= y 0))) + (group-by first) + (filter (fn [[k v]] + (> (count v) 1))) + + (map (fn [[k vs]] + (let [[yodlee-id & old] (->> vs + (sort-by second) + (map (fn [[_ _ yodlee-id date]] + [yodlee-id date])) + + (reverse))] + [k {:new-yodlee-id yodlee-id + :defunct-yodlee-ids (clojure.set/difference (set old) #{yodlee-id})}]))) + + (mapv (fn [[bank-account history]] + (d/query {:query {:find '[?t] #_['(pull $2 ?t [*]) '(pull $2 ?t2 [*])] + :in ['$ '$2 '?bank-account '?before] + :where ['[?t :transaction/bank-account ?bank-account] + '[?t :transaction/date ?date] + '[?t :transaction/amount ?tx-amount ?tx true] + '[?tx :db/txInstant ?tx-date] + '[(< ?tx-date ?before)] + '[?t2 :transaction/bank-account ?bank-account] + '[?t2 :transaction/amount ?tx-amount2 ?tx2 true] + '[?tx2 :db/txInstant ?tx2-date] + '[?t2 :transaction/date ?date] + '[(auto-ap.utils/dollars= ?tx-amount ?tx-amount2)] + '[(not= ?t ?t2)] + '[(> ?tx2-date ?before)] + ]} + :args [(d/history (d/db (d/connect uri))) (d/db (d/connect uri)) bank-account (second (:new-yodlee-id history))]}))) + + ) + + +20186866 24265567 24370736 +(auto-ap.yodlee.core/get-specific-transactions 24265567) + + +(def bad-account-ids (->> (d/query {:query {:find ['?e '?tx '?yai '?d] + :in ['$] + :where ['[?e :bank-account/yodlee-account-id ?yai ?tx true] + '[?tx :db/txInstant ?d]]} + :args [(d/history (d/db (d/connect uri)))]}) + (filter (fn [[_ _ y]] + (not= y 0))) + (group-by first) + (filter (fn [[k v]] + (> (count v) 1))) + (keys))) + +(count + (->> (d/query {:query {:find ['?bank-account '?date '?tx-amount '?tx-account] + :in ['$] + :where ['[?t :transaction/client [:client/code "NGO"]] + '[?t :transaction/bank-account ?bank-account] + '[?t :transaction/date ?date] + '[?t :transaction/amount ?tx-amount ] + '[?t :transaction/account-id ?tx-account ] + ]} + :args [(d/db (d/connect uri))]}) + (group-by (fn [[ba date amount _]] + [ba date amount])) + (mapv (fn [[k v]] + [k (set (map last v))])) + (filter (fn [[k v]] + (> (count v) 1))))) + +;; FINDS TRANSACTIONS THAT COME FROM DIFFERENT YODLEE IDS + +(reduce + (fn [acc [k v]] + (update acc k conj v) + ) + {} + (mapcat (fn [ba] + (->> (d/query {:query {:find ['?code '?date '?tx-amount '?t '?tx-account ] + :in ['$ '?bank-account] + :where ['[?t :transaction/bank-account ?bank-account] + '[?bank-account :bank-account/code ?code] + '[?t :transaction/date ?date] + '[?t :transaction/amount ?tx-amount ] + '[?t :transaction/account-id ?tx-account ] + '[(>= ?date #inst "2020-01-01")] + ]} + :args [(d/db (d/connect uri) ) ba]}) + (group-by (fn [[ba date amount _]] + [ba date amount])) + (filter (fn [[k v]] + (> (count (set (map last v))) 1))) + (map second) + (mapcat identity) + (map (fn [[ba _ _ id act]] + [[ba act] id])) + + #_(map (fn [[_ []]])) + #_(mapv (fn [[k v]] + [k (reduce + (fn [acc [_ _ _ act id]] + (assoc acc act id )) + {} + v)])) + + #_(map second) + )) + bad-account-ids)) + +;; delete +(->> (d/pull-many (d/db (d/connect uri)) '[:db/id {:journal-entry/_original-entity [:db/id]}] '(17592232564344)) + (mapcat (fn [x] + [[:db/retractEntity (:db/id x)] + [:db/retractEntity (:db/id (first (:journal-entry/_original-entity x)))]])) + (d/transact (d/connect uri) ) + deref)) diff --git a/scratch-sessions/make_ledger_fast_again.clj b/scratch-sessions/make_ledger_fast_again.clj index e213f778..d396a88e 100644 --- a/scratch-sessions/make_ledger_fast_again.clj +++ b/scratch-sessions/make_ledger_fast_again.clj @@ -58,53 +58,58 @@ (or (:db/ident (:account/type (accounts a))) ({:bank-account-type/check :account-type/asset :bank-account-type/credit :account-type/liability} - (:db/ident (:bank-account/type (bank-accounts a))))))] - (->> (d/query - {:query {:find ['?d '?jel '?account '?location '?debit '?credit ] - :in ['$ '?client-id] - :where ['[?e :journal-entry/client ?client-id] - '[?e :journal-entry/date ?d] - '[(<= ?d #inst "2020-09-01")] - '[?e :journal-entry/line-items ?jel] - '[(get-else $ ?jel :journal-entry-line/account :account/unknown) ?account] - '[(get-else $ ?jel :journal-entry-line/debit 0.0) ?debit] - '[(get-else $ ?jel :journal-entry-line/credit 0.0) ?credit] - '[(get-else $ ?jel :journal-entry-line/location "") ?location]] - } - :args [(d/db (d/connect uri)) client-id]}) - (sort-by first) + (:db/ident (:bank-account/type (bank-accounts a)))))) + all-ledger-entries (->> (d/query + {:query {:find ['?d '?jel '?account '?location '?debit '?credit ] + :in ['$ '?client-id] + :where ['[?e :journal-entry/client ?client-id] + '[?e :journal-entry/date ?d] + '[(<= ?d #inst "2020-09-01")] + '[?e :journal-entry/line-items ?jel] + '[(get-else $ ?jel :journal-entry-line/account :account/unknown) ?account] + '[(get-else $ ?jel :journal-entry-line/debit 0.0) ?debit] + '[(get-else $ ?jel :journal-entry-line/credit 0.0) ?credit] + '[(get-else $ ?jel :journal-entry-line/location "") ?location]] + } + :args [(d/db (d/connect uri)) client-id]}) + (sort-by first))] - (reduce - (fn [acc [_ _ account location debit credit]] - (-> acc - (update-in [[location account] :debit] (fnil + 0.0) debit) - (update-in [[location account] :credit] (fnil + 0.0) credit) - (update-in [[location account] :count] (fnil + 0) 1)) - ) - {}) - (reduce-kv - (fn [acc [location account] {:keys [debit credit count]}] - (let [account-type (account->type account)] - (conj acc {:name (if-not (= "A" location) - (str (account->name account) "-" location) - (account->name account)) - :id (str account "-" location) - :numeric_code (account->numeric-code account) - :location (or location "") - :amount (if account-type (if (#{:account-type/asset - :account-type/dividend - :account-type/expense} account-type) - (- debit credit) - (- credit debit) - ) - 0.0) - :account_type account-type})) - ) + (reduce + (fn [acc bracket] + (println (first all-ledger-entries)) + (assoc acc bracket (->> all-ledger-entries + (filter (fn [[d]] + (<= (compare d bracket) 0))) + (reduce + (fn [acc [_ _ account location debit credit]] + (-> acc + (update-in [[location account] :debit] (fnil + 0.0) debit) + (update-in [[location account] :credit] (fnil + 0.0) credit) + (update-in [[location account] :count] (fnil + 0) 1)) + ) + {}) + (reduce-kv + (fn [acc [location account] {:keys [debit credit count]}] + (let [account-type (account->type account)] + (conj acc {:name (if-not (= "A" location) + (str (account->name account) "-" location) + (account->name account)) + :id (str account "-" location) + :numeric_code (account->numeric-code account) + :location (or location "") + :amount (if account-type (if (#{:account-type/asset + :account-type/dividend + :account-type/expense} account-type) + (- debit credit) + (- credit debit) + ) + 0.0) + :account_type account-type})) + ) - []) - #_(map (juxt :name :count (comp int :amount))) - #_(sort-by first) - )) + [])))) + {} + brackets)) ) ;; 9804 diff --git a/src/clj/auto_ap/datomic/invoices.clj b/src/clj/auto_ap/datomic/invoices.clj index 3eb0dec3..6823d955 100644 --- a/src/clj/auto_ap/datomic/invoices.clj +++ b/src/clj/auto_ap/datomic/invoices.clj @@ -137,13 +137,13 @@ (defn sum-outstanding [ids] (->> - (d/query {:query {:find ['?o] + (d/query {:query {:find ['?id '?o] :in ['$ '[?id ...]] :where ['[?id :invoice/outstanding-balance ?o]] } :args [(d/db (d/connect uri)) ids]}) - (map first) + (map last) (reduce + 0.0))) diff --git a/src/clj/auto_ap/yodlee/core.clj b/src/clj/auto_ap/yodlee/core.clj index e92d4217..ea046646 100644 --- a/src/clj/auto_ap/yodlee/core.clj +++ b/src/clj/auto_ap/yodlee/core.clj @@ -282,6 +282,7 @@ :body (json/write-str data) :as :json})) (refresh-provider-account pa))) + #_(defn get-users [] (let [cob-session (login-cobrand)] (-> "https://developer.api.yodlee.com/ysl/user" diff --git a/src/cljs/auto_ap/views/pages/ledger/profit_and_loss.cljs b/src/cljs/auto_ap/views/pages/ledger/profit_and_loss.cljs index 4e80dec6..e21d2f4d 100644 --- a/src/cljs/auto_ap/views/pages/ledger/profit_and_loss.cljs +++ b/src/cljs/auto_ap/views/pages/ledger/profit_and_loss.cljs @@ -6,7 +6,7 @@ [goog.string :as gstring] [auto-ap.utils :refer [dollars-0? by ]] [auto-ap.views.pages.ledger.side-bar :refer [ledger-side-bar]] - [auto-ap.views.utils :refer [date->str date-picker bind-field standard dispatch-event local-now ->% ->$ str->date with-user]] + [auto-ap.views.utils :refer [date->str date-picker bind-field standard pretty dispatch-event local-now ->% ->$ str->date with-user]] [cljs-time.core :as t] [re-frame.core :as re-frame])) (def ranges @@ -172,7 +172,6 @@ (re-frame/reg-event-fx ::params-change (fn [cofx [_ params]] - (println params) (let [c @(re-frame/subscribe [::subs/client])] (cond-> {:db (-> (:db cofx) (assoc-in [::error] nil) @@ -302,48 +301,65 @@ (set) (sort-by :numeric-code))) - -(defn grouping [{:keys [header type groupings location]}] - (let [periods @(re-frame/subscribe [::periods]) - all-accounts @(re-frame/subscribe [::all-accounts])] +(defn map-periods [for-every between periods] + (for [[_ i] (map vector periods (range))] + ^{:key (str "period-" i)} [:<> - (doall - (for [[grouping-name from to] groupings - :let [account-codes (used-accounts all-accounts [from to] location)] - :when (seq account-codes)] - ^{:key grouping-name} - [:<> - [:tr [:td "---" grouping-name "---"] - (for [[_ i] (map vector periods (range))] - [:<> - [:td] - [:td] - (when (not= 0 i) - [:td])])] - [:<> - (for [{:keys [numeric-code name]} account-codes] - ^{:key numeric-code} - [:tr [:td name] - (for [[p i] (map vector periods (range)) - :let [amount (get-in all-accounts [i [numeric-code location] :amount] 0.0)]] - [:<> - [:td.has-text-right [:a {:on-click (dispatch-event [::investigate-clicked location numeric-code numeric-code i :current])} - (->$ amount)]] - [:td.has-text-right (->% (percent-of-sales amount all-accounts i location))] - (when (not= 0 i) - [:td.has-text-right (->$ (- amount - (get-in all-accounts [(dec i) [numeric-code location] :amount] 0.0)))])])])] + (with-meta + (for-every i) + {:key i}) + (if (not= 0 i) + (with-meta (between i) + {:key (str "between-" i)}))])) - [:tr [:th ] - (for [[p i] (map vector periods (range)) - :let [amount (aggregate-accounts (filter-accounts all-accounts i [from to] location))]] - [:<> - [:th.has-text-right.total [:a {:on-click (dispatch-event [::investigate-clicked location from to i])} - (->$ amount)]] - [:th.has-text-right.total (->% (percent-of-sales amount all-accounts i location))] - (when (not= 0 i) - [:th.has-text-right.total (->$ (- amount - (aggregate-accounts (filter-accounts all-accounts (dec i) [from to] location))))])])]]))])) + +(defn grouping [{:keys [header type groupings location periods all-accounts]}] + [:<> + (doall + (for [[grouping-name from to] groupings + :let [account-codes (used-accounts all-accounts [from to] location)] + :when (seq account-codes)] + ^{:key grouping-name} + [:<> + [:tr [:td "---" grouping-name "---"] + (map-periods + (fn [i] + [:<> + [:td] + [:td]]) + (fn [i] + [:td]) + periods)] + [:<> + (for [{:keys [numeric-code name]} account-codes] + ^{:key numeric-code} + [:tr + [:td name] + (map-periods + (fn [i] + (let [amount (get-in all-accounts [(dec i) [numeric-code location] :amount] 0.0)] + [:<> + [:td.has-text-right [:a {:on-click (dispatch-event [::investigate-clicked location numeric-code numeric-code i :current])} + (->$ amount)]] + [:td.has-text-right (->% (percent-of-sales amount all-accounts i location))]])) + (fn [i] + [:td.has-text-right (->$ (- (get-in all-accounts [(dec i) [numeric-code location] :amount] 0.0) + (get-in all-accounts [(dec i) [numeric-code location] :amount] 0.0)))]) + periods)])] + + [:tr + [:th] + (map-periods + (fn [i] + (let [amount (aggregate-accounts (filter-accounts all-accounts i [from to] location))] + [:<> + [:th.has-text-right.total [:a {:on-click (dispatch-event [::investigate-clicked location from to i])} + (->$ amount)]] + [:th.has-text-right.total (->% (percent-of-sales amount all-accounts i location))]])) + (fn [i] + [:th.has-text-right.total (->$ (- (aggregate-accounts (filter-accounts all-accounts i [from to] location)) + (aggregate-accounts (filter-accounts all-accounts (dec i) [from to] location))))]) + periods)]]))]) @@ -356,42 +372,49 @@ [:tr [:th.is-size-5 title]] [grouping {:location location - :groupings (type groupings)}] + :groupings (type groupings) + :periods periods + :all-accounts all-accounts}] [:tr [:th.is-size-5 title] - (for [[i p] (map vector (range) periods) - :let [amount (aggregate-accounts (filter-accounts all-accounts i [min-numeric-code max-numeric-code] location))]] - - [:<> - [:th.has-text-right [:a - {:on-click (dispatch-event [::investigate-clicked location min-numeric-code max-numeric-code i])} - (->$ amount)]] - [:th.has-text-right (->% (percent-of-sales amount all-accounts i location))] - (when (not= 0 i) - [:th.has-text-right (->$ (- amount - (aggregate-accounts (filter-accounts all-accounts (dec i) [min-numeric-code max-numeric-code] location))))])])]])) + (map-periods + (fn [i] + (let [amount (aggregate-accounts (filter-accounts all-accounts i [min-numeric-code max-numeric-code] location))] + [:<> + [:th.has-text-right [:a + {:on-click (dispatch-event [::investigate-clicked location min-numeric-code max-numeric-code i])} + (->$ amount)]] + [:th.has-text-right (->% (percent-of-sales amount all-accounts i location))] + ])) + (fn [i] + [:th.has-text-right (->$ (- (aggregate-accounts (filter-accounts all-accounts i [min-numeric-code max-numeric-code] location)) + (aggregate-accounts (filter-accounts all-accounts (dec i) [min-numeric-code max-numeric-code] location))))]) + periods)]])) (defn subtotal [types negs title location] (let [all-accounts @(re-frame/subscribe [::all-accounts]) periods @(re-frame/subscribe [::periods])] [:tr [:th.is-size-5 title] - (for [[p i] (map vector periods (range)) - :let [amount (aggregate-accounts (mapcat (fn [t] - (cond->> (filter-accounts all-accounts i (ranges t) location) - (negs t) (map #(update % :amount -)))) - types))]] - [:<> - [:td.has-text-right [:span (->$ amount)]] - [:td.has-text-right (->% (percent-of-sales amount all-accounts i location))] - (when (not= 0 i) - [:td.has-text-right (->$ (- amount - (aggregate-accounts (mapcat (fn [t] - (cond->> (filter-accounts all-accounts (dec i) (ranges t) location) - (negs t) (map #(update % :amount -)))) - types))))] - ) - ])])) + (map-periods + (fn [i] + (let [amount (aggregate-accounts (mapcat (fn [t] + (cond->> (filter-accounts all-accounts i (ranges t) location) + (negs t) (map #(update % :amount -)))) + types))] + [:<> + [:td.has-text-right [:span (->$ amount)]] + [:td.has-text-right (->% (percent-of-sales amount all-accounts i location))]])) + (fn [i] + [:td.has-text-right (->$ (- (aggregate-accounts (mapcat (fn [t] + (cond->> (filter-accounts all-accounts i (ranges t) location) + (negs t) (map #(update % :amount -)))) + types)) + (aggregate-accounts (mapcat (fn [t] + (cond->> (filter-accounts all-accounts (dec i) (ranges t) location) + (negs t) (map #(update % :amount -)))) + types))))]) + periods)])) (defn location-rows [location] @@ -416,13 +439,16 @@ [:tbody [:tr [:td.has-text-right "Period ending"] - (for [[[_ date] i] (map vector periods (range))] - [:<> - [:td.has-text-right (when date - (date->str date))] - [:td] - (when (not= 0 i) - [:td])])] + (map-periods + (fn [i] + [:<> + [:td.has-text-right (when-let [ date (get-in periods [i 1])] + (date->str date))] + [:td] + ]) + (fn [i] + [:td]) + periods)] [subtotal [:sales ] #{} "Sales" location] [subtotal [:cogs ] #{} "Cogs" location] [subtotal [:payroll ]#{} "Payroll" location] @@ -456,7 +482,7 @@ [:h2.title.is-4 "Range"] [:div [:div.field.is-grouped - [:p.control + [:div.control [:a.button {:class (when (= (:selected params) "13 periods") "is-active") :on-click (dispatch-event @@ -473,7 +499,7 @@ "13 periods"])} "13 periods"]] - [:p.control + [:div.control [:a.button {:class (when (= (:selected params) "Last week") "is-active") :on-click (dispatch-event @@ -485,7 +511,7 @@ (and-last-year [(t/minus last-sunday (t/period :days 6)) last-sunday]) "Last week"]))} "Last week"]] - [:p.control + [:div.control [:a.button {:class (when (= (:selected params) "Week to date") "is-active") :on-click (dispatch-event [::range-selected @@ -496,7 +522,7 @@ (local-now)]) "Week to date"])} "Week to date"]] - [:p.control + [:div.control [:a.button {:class (when (= (:selected params) "Last Month") "is-active") :on-click (dispatch-event [::range-selected @@ -510,7 +536,7 @@ (t/period :days 1))]) "Last Month"])} "Last Month"]] - [:p.control + [:div.control [:a.button {:class (when (= (:selected params) "Month to date") "is-active") :on-click (dispatch-event [::range-selected @@ -520,7 +546,7 @@ (local-now)]) "Month to date"])} "Month to date"]] - [:p.control + [:div.control [:a.button {:class (when (= (:selected params) "Year to date") "is-active") :on-click (dispatch-event [::range-selected @@ -528,7 +554,7 @@ (local-now)]) "Year to date"])} "Year to date"]] - [:p.control + [:div.control [:a.button {:class (when (= (:selected params) "Full year") "is-active") :on-click (dispatch-event [::range-selected @@ -538,8 +564,9 @@ "Full year"])} "Full year"]]]] (for [[_ i] (map vector periods (range))] + ^{:key i} [:div.field.is-grouped - [:p.control + [:div.control [:p.help "From"] [bind-field [date-picker {:class-name "input" @@ -555,7 +582,7 @@ :popper-props (clj->js {:placement "right"}) :subscription params}]]] - [:p.control + [:div.control [:p.help "To"] [bind-field [date-picker {:class-name "input" @@ -589,15 +616,14 @@ [:tbody [:tr [:td.has-text-right "Period Ending"] - [:td.has-text-right (date->str (last (first periods)))] - [:td] - [:<> - (for [[_ end] (rest periods)] + (map-periods + (fn [i] [:<> - [:td.has-text-right (date->str end)] - [:td] - [:td.has-text-right "𝝙"]] - )]] + [:td.has-text-right (date->str (get-in periods [i 1]))] + [:td]]) + (fn [i] + [:td.has-text-right "𝝙"]) + periods)] [:<> (for [location @(re-frame/subscribe [::locations])] ^{:key location} diff --git a/src/cljs/auto_ap/views/utils.cljs b/src/cljs/auto_ap/views/utils.cljs index 9ab9637a..eee81578 100644 --- a/src/cljs/auto_ap/views/utils.cljs +++ b/src/cljs/auto_ap/views/utils.cljs @@ -183,7 +183,7 @@ (instance? goog.date.DateTime selected) - (c/to-date selected) + (c/to-date (time/to-default-time-zone (time/from-default-time-zone selected))) (instance? goog.date.Date selected) (c/to-date selected)