diff --git a/config/prod.edn b/config/prod.edn index 24fe5e59..8b18ce86 100644 --- a/config/prod.edn +++ b/config/prod.edn @@ -13,4 +13,6 @@ :yodlee-base-url "https://quickstart2.api.yodlee.com/ysl" :yodlee-app "10003600" :yodlee-fastlink "https://quickstartus2node.yodleeinteractive.com/authenticate/qstartus12/?channelAppName=quickstartus2" + :yodlee-proxy-host "172.31.10.83" + :yodlee-proxy-port 8888 } diff --git a/src/clj/auto_ap/yodlee/import.clj b/src/clj/auto_ap/yodlee/import.clj index 20756381..67e789b4 100644 --- a/src/clj/auto_ap/yodlee/import.clj +++ b/src/clj/auto_ap/yodlee/import.clj @@ -16,7 +16,8 @@ [unilog.context :as lc] [clojure.tools.logging :as log] [clj-time.core :as t] - [mount.core :as mount])) + [mount.core :as mount] + [yang.scheduler :as scheduler])) (defn rough-match [client-id bank-account-id amount] @@ -208,4 +209,4 @@ (mount/defstate import-transaction-worker :start (scheduler/every (* 1000 60 60 4) do-import) - :stop (scheduler/stop import-transactions-cleared-against)) + :stop (scheduler/stop import-transaction-worker)) 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 907b2864..5fea57a9 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 @@ -5,7 +5,9 @@ [vimsical.re-frame.cofx.inject :as inject] [goog.string :as gstring] [auto-ap.utils :refer [dollars-0? by ]] + [auto-ap.forms :as forms] [auto-ap.views.pages.ledger.side-bar :refer [ledger-side-bar]] + [auto-ap.views.components.modal :as modal] [auto-ap.views.utils :refer [date->str date-picker bind-field standard pretty dispatch-event local-today ->% ->$ str->date with-user dispatch-value-change query-params]] [cljs-time.core :as t] [re-frame.core :as re-frame] @@ -14,7 +16,8 @@ [vimsical.re-frame.fx.track :as track] [reagent.core :as reagent] [clojure.set :as set] - [clojure.string :as str])) + [clojure.string :as str] + [cljs-time.core :as time])) (def ranges {:sales [40000 49999] :cogs [50000 59999] @@ -262,6 +265,98 @@ :date-range {:start (date->str from standard) :end (date->str to standard)}}]}))) +(re-frame/reg-sub + ::can-submit-period-form + (fn [] + true)) + +(def change-period-form (forms/vertical-form {:submit-event [::change-period] + :change-event [::forms/change ::period-form] + :can-submit [::can-submit-period-form] + :id ::period-form})) + +(defn change-period-body [idx which] + (let [{:keys [data active? error id]} @(re-frame/subscribe [::forms/form ::period-form]) + {:keys [form-inline horizontal-field field raw-field error-notification submit-button]} change-period-form] + (form-inline {} + [:<> + (field "From" + [date-picker {:class-name "input" + :class "input" + :format-week-number (fn [] "") + :previous-month-button-label "" + :placeholder "mm/dd/yyyy" + :next-month-button-label "" + :next-month-label "" + :type "date" + :field [:period 0] + :popper-props (clj->js {:placement "right"}) + }] ) + (field "To" + [date-picker {:class-name "input" + :class "input" + :format-week-number (fn [] "") + :previous-month-button-label "" + :placeholder "mm/dd/yyyy" + :next-month-button-label "" + :next-month-label "" + :type "date" + :field [:period 1] + :popper-props (clj->js {:placement "right"}) + }] )]))) +(re-frame/reg-event-fx + ::period-change-submitted + (fn [{:keys [db]} [_ idx which]] + { :db (-> db (forms/stop-form ::period-form) + (assoc-in [::periods idx] which)) + :dispatch-n [[::modal/modal-closed ] + [::range-selected (assoc (::periods db) idx which) nil nil]]})) + +(re-frame/reg-event-fx + ::period-removed + (fn [{:keys [db]} [_ idx which]] + { :db (-> db (forms/stop-form ::period-form) + (update ::periods (fn [ps] + (->> ps + (map vector (range) ) + (filter (fn [[i _]] + (not= i idx))) + (map second) + (into []))))) + :dispatch [::modal/modal-closed ]})) + +(defn change-period-foot [idx which] + [:div.buttons + [:button.button {:class "is-primary" + :on-click (dispatch-event [::period-change-submitted idx + (-> @(re-frame/subscribe [::forms/form ::period-form]) + :data + :period + (update 0 #(if (instance? goog.date.Date %) + % + (str->date % standard))) + (update 1 #(if (instance? goog.date.Date %) + % + (str->date % standard))) + )])} + "Change period"] + [:button.button {:class "is-warning" + :on-click (dispatch-event [::period-removed idx ])} + "Delete period"]] + + ) +(re-frame/reg-event-fx + ::period-change-requested + (fn [{:keys [db]} [_ idx which]] + { :db (-> db + (forms/start-form ::period-form + {:idx idx + :period which})) + :dispatch [::modal/modal-requested {:title (str "Change period " (date->str (nth which 0)) " - " (date->str (nth which 1))) + :class "" + :body [change-period-body idx which] + :foot [change-period-foot idx which]}]})) + (def groupings {:sales [["40000-43999 Food Sales " 40000 43999] ["44000-46999 Alcohol Sales" 44000 46999] @@ -438,6 +533,35 @@ periods (:include-deltas params))])) +(defn period-header [{:keys [include-deltas periods]}] + [:<> + [:tr + [:td.has-text-right "Period"] + (map-periods + (fn [i] + [:<> + [:td.has-text-centered {:colspan 2} + [:a {:on-click (dispatch-event [::period-change-requested i (get periods i)])} + (or (get-in periods [i 2]) + (str (date->str (get-in periods [i 0])) " - " (date->str (get-in periods [i 1]))))]]]) + (fn [i] + [:td.has-text-right ""]) + periods + include-deltas)] + [:tr + [:td.has-text-right ""] + (map-periods + (fn [i] + [:<> + [:td.has-text-right + "Amount"] + [:td.has-text-right + "% Sales"]]) + (fn [i] + [:td.has-text-right "𝝙"]) + periods + include-deltas)]]) + (defn location-rows [location] [:<> @@ -459,21 +583,10 @@ [:h2.title.is-4.mb-4 location " Summary"] [:table.table.compact.balance-sheet.mb-6 [:tbody - [:tr - [:td.has-text-right "Period ending"] - (map-periods - (fn [i] - [:<> - [:td.has-text-right - (or (get-in periods [i 2]) - (when-let [ date (get-in periods [i 1])] - (date->str date)))] - [:td] - ]) - (fn [i] - [:td]) - periods - (:include-deltas params))] + [period-header {:include-deltas (:include-deltas params) + :periods periods}] + + [subtotal [:sales ] #{} "Sales" location] [subtotal [:cogs ] #{} "Cogs" location] [subtotal [:payroll ]#{} "Payroll" location] @@ -498,11 +611,11 @@ (if-not current-client [:div - [:h1.title "Profit and Loss"] + [:h1.title "Profit and Loss " ] [:h2.title.is-4 "Please choose a client first"]] [:div - [:h1.title "Profit and Loss"] + [:h1.title "Profit and Loss - " (:name current-client)] [status/status-notification {:statuses [[::status/single ::page]]}] [:div.report-controls [:h2.title.is-4 "Range"] @@ -717,19 +830,9 @@ [:h2.title.is-4 {:style {:margin-bottom "1rem"}} "Detail"] [:table.table.compact.balance-sheet [:tbody - [:tr - [:td.has-text-right "Period Ending"] - (map-periods - (fn [i] - [:<> - [:td.has-text-right - (or (get-in periods [i 2]) - (date->str (get-in periods [i 1])))] - [:td]]) - (fn [i] - [:td.has-text-right "𝝙"]) - periods - (:include-deltas params))] + [period-header {:include-deltas (:include-deltas params) + :periods periods}] + [:<> (for [location @(re-frame/subscribe [::locations])] ^{:key location}