From 1b56bc9324887952f9a0caecad0f93aa4028c24e Mon Sep 17 00:00:00 2001 From: Bryce Covert Date: Thu, 24 Sep 2020 13:02:37 -0700 Subject: [PATCH] now you can schedule dom. --- src/clj/auto_ap/routes/invoices.clj | 53 ++++++++++-------- src/cljc/auto_ap/time_utils.cljc | 15 ++++++ .../auto_ap/views/pages/invoices/form.cljs | 54 +++++++++++++------ src/cljs/auto_ap/views/utils.cljs | 1 - 4 files changed, 85 insertions(+), 38 deletions(-) create mode 100644 src/cljc/auto_ap/time_utils.cljc diff --git a/src/clj/auto_ap/routes/invoices.clj b/src/clj/auto_ap/routes/invoices.clj index c6d0a7d0..c8022ff7 100644 --- a/src/clj/auto_ap/routes/invoices.clj +++ b/src/clj/auto_ap/routes/invoices.clj @@ -1,28 +1,27 @@ (ns auto-ap.routes.invoices - (:require [auto-ap.datomic.clients :as d-clients] - [auto-ap.datomic.vendors :as d-vendors] - [auto-ap.datomic.invoices :as d-invoices] + (:require [auto-ap.datomic :refer [remove-nils uri]] [auto-ap.datomic.accounts :as d-accounts] - [auto-ap.yodlee.import :refer [manual-import]] - [auto-ap.utils :refer [by]] - [auto-ap.datomic :refer [remove-nils uri]] - [datomic.api :as d] + [auto-ap.datomic.clients :as d-clients] + [auto-ap.datomic.invoices :as d-invoices] + [auto-ap.datomic.vendors :as d-vendors] + [auto-ap.graphql.utils :refer [assert-admin]] + [auto-ap.logging :refer [info-event]] [auto-ap.parse :as parse] [auto-ap.parse.util :as parse-u] - [auto-ap.graphql.utils :refer [assert-admin]] [auto-ap.routes.utils :refer [wrap-secure]] - - [clj-time.core :as time] + [auto-ap.time-utils :refer [next-dom]] + [auto-ap.utils :refer [by]] + [auto-ap.yodlee.import :refer [manual-import]] [clj-time.coerce :as coerce :refer [to-date]] - [ring.middleware.json :refer [wrap-json-response]] - [compojure.core :refer [GET POST context defroutes - wrap-routes]] - [clojure.string :as str] - [clojure.java.io :as io] + [clj-time.core :as time] [clojure.data.csv :as csv] - [unilog.context :as lc] + [clojure.java.io :as io] + [clojure.string :as str] [clojure.tools.logging :as log] - [auto-ap.logging :refer [info-event]])) + [compojure.core :refer [context defroutes POST wrap-routes]] + [datomic.api :as d] + [ring.middleware.json :refer [wrap-json-response]] + [unilog.context :as lc])) (defn reset-id [i] (update i :invoice-number @@ -70,6 +69,10 @@ (defn parse-automatically-paid-when-due [{:keys [vendor client-id]}] (boolean ((set (map :db/id (:vendor/automatically-paid-when-due vendor))) client-id))) +(defn parse-schedule-payment-dom [{:keys [vendor client-id]}] + (get (by (comp :db/id :vendor-schedule-payment-dom/client) :vendor-schedule-payment-dom/dom (:vendor/schedule-payment-dom vendor)) + client-id)) + (defn parse-amount [i] (try (Double/parseDouble (str/replace (or (second @@ -128,6 +131,7 @@ (map (parse-or-error :vendor #(parse-vendor % all-vendors))) (map (parse-or-error :vendor-id #(parse-vendor-id %))) (map (parse-or-error :automatically-paid-when-due #(parse-automatically-paid-when-due %))) + (map (parse-or-error :schedule-payment-dom #(parse-schedule-payment-dom %))) (map (parse-or-error :account-id parse-account-numeric-code)) (map (parse-or-error :invoice-number parse-invoice-number)) (map (parse-or-error :total parse-amount)) @@ -138,7 +142,7 @@ (defn invoice-rows->transaction [rows] (->> rows - (mapcat (fn [{:keys [vendor-id total client-id amount date invoice-number default-location account-id check vendor automatically-paid-when-due]}] + (mapcat (fn [{:keys [vendor-id total client-id amount date invoice-number default-location account-id check vendor automatically-paid-when-due schedule-payment-dom]}] (let [invoice (cond-> #:invoice {:db/id (.toString (java.util.UUID/randomUUID)) :vendor vendor-id @@ -163,7 +167,10 @@ (:vendor/terms vendor) (assoc :invoice/due (coerce/to-date (time/plus date (time/days (d-vendors/terms-for-client-id vendor client-id))))) automatically-paid-when-due (assoc :invoice/scheduled-payment (coerce/to-date - (time/plus date (time/days (d-vendors/terms-for-client-id vendor client-id)))))) + (time/plus date (time/days (d-vendors/terms-for-client-id vendor client-id))))) + schedule-payment-dom (assoc :invoice/scheduled-payment (coerce/to-date + (next-dom date schedule-payment-dom) + ))) payment (if (= :invoice-status/paid (:invoice/status invoice)) #:invoice-payment {:invoice (:db/id invoice) :amount (:invoice/total invoice) @@ -260,7 +267,9 @@ (.toString e)) {:args [ invoice-number matching-vendor (:db/id matching-client)]}))) )) - automatically-paid-for (set (map :db/id (:vendor/automatically-paid-when-due matching-vendor)))] + automatically-paid-for (set (map :db/id (:vendor/automatically-paid-when-due matching-vendor))) + schedule-payment-dom (get (by (comp :db/id :vendor-schedule-payment-dom/client) :vendor-schedule-payment-dom/dom (:vendor/schedule-payment-dom matching-vendor)) + (:db/id matching-client))] (cond (not (and matching-location matching-client)) @@ -287,7 +296,9 @@ (:vendor/terms matching-vendor) (assoc :invoice/due (coerce/to-date (time/plus date (time/days (d-vendors/terms-for-client-id matching-vendor (:db/id matching-client)))))) (boolean (automatically-paid-for (:db/id matching-client))) (assoc :invoice/scheduled-payment (coerce/to-date - (time/plus date (time/days (d-vendors/terms-for-client-id matching-vendor (:db/id matching-client))))))))) + (time/plus date (time/days (d-vendors/terms-for-client-id matching-vendor (:db/id matching-client)))))) + schedule-payment-dom (assoc :invoice/scheduled-payment (to-date + (next-dom date schedule-payment-dom)))))) )) [] imports)] diff --git a/src/cljc/auto_ap/time_utils.cljc b/src/cljc/auto_ap/time_utils.cljc new file mode 100644 index 00000000..a99dafe5 --- /dev/null +++ b/src/cljc/auto_ap/time_utils.cljc @@ -0,0 +1,15 @@ +(ns auto-ap.time-utils + (:require #?(:clj [clj-time.core :as time] + :cljs [cljs-time.core :as time]))) + +(defn next-dom [date dom] + (when date + (let [candidate (time/date-time (time/year date) (time/month date) + #?(:clj (Math/min (int dom) + (time/day (time/last-day-of-the-month (time/year date) (time/month date)))) + :cljs (Math/min dom + (time/day (time/last-day-of-the-month (time/year date) (time/month date))))))] + + (if (time/before? candidate date) + (time/plus candidate (time/months 1)) + candidate)))) diff --git a/src/cljs/auto_ap/views/pages/invoices/form.cljs b/src/cljs/auto_ap/views/pages/invoices/form.cljs index 74887dfd..aed9a6c4 100644 --- a/src/cljs/auto_ap/views/pages/invoices/form.cljs +++ b/src/cljs/auto_ap/views/pages/invoices/form.cljs @@ -2,23 +2,30 @@ (:require [auto-ap.entities.invoice :as invoice] [auto-ap.events :as events] [auto-ap.forms :as forms] + [auto-ap.status :as status] [auto-ap.subs :as subs] - [auto-ap.utils :refer [dollars=]] + [auto-ap.utils :refer [by dollars=]] [auto-ap.views.components.dropdown :refer [drop-down]] - [auto-ap.views.components.expense-accounts-field :as expense-accounts-field :refer [expense-accounts-field recalculate-amounts]] + [auto-ap.time-utils :refer [next-dom]] + [auto-ap.views.components.expense-accounts-field + :as + expense-accounts-field + :refer + [expense-accounts-field recalculate-amounts]] [auto-ap.views.components.layouts :as layouts] [auto-ap.views.components.money-field :refer [money-field]] [auto-ap.views.components.switch-field :refer [switch-field]] [auto-ap.views.components.typeahead :refer [typeahead-entity]] [auto-ap.views.pages.invoices.common :refer [invoice-read]] - [auto-ap.status :as status] - [auto-ap.views.utils :refer [date->str date-picker dispatch-event standard with-user]] + [auto-ap.views.utils + :refer + [date->str date-picker dispatch-event standard with-user str->date]] [cljs-time.core :as c] [clojure.spec.alpha :as s] [clojure.string :as str] [re-frame.core :as re-frame] - [vimsical.re-frame.fx.track :as track] - [reagent.core :as r])) + [reagent.core :as r] + [vimsical.re-frame.fx.track :as track])) ;; SUBS (re-frame/reg-sub @@ -156,6 +163,8 @@ locations)}))))) + + (re-frame/reg-event-db ::changed (forms/change-handler ::form @@ -163,21 +172,34 @@ (let [locations @(re-frame/subscribe [::subs/locations-for-client (:id (:client data))])] (cond (and (= [:vendor] field) value) - (cond-> [] - (expense-accounts-field/can-replace-with-default? (:expense-accounts data)) - (into [[:expense-accounts] (expense-accounts-field/default-account (:expense-accounts data) - @(re-frame/subscribe [::subs/vendor-default-account value (:client data)]) - (:total data) - locations)]) + (let [schedule-payment-dom (get (by (comp :id :client ) :dom (:schedule-payment-dom value)) + (:id (:client data)))] + (cond-> [] + (expense-accounts-field/can-replace-with-default? (:expense-accounts data)) + (into [[:expense-accounts] (expense-accounts-field/default-account (:expense-accounts data) + @(re-frame/subscribe [::subs/vendor-default-account value (:client data)]) + (:total data) + locations)]) - - (boolean ((set (map :id (:automatically-paid-when-due value))) (:id (:client data)))) - (into [[:scheduled-payment] (:due data) - [:schedule-when-due] true])) + + (boolean ((set (map :id (:automatically-paid-when-due value))) (:id (:client data)))) + (into [[:scheduled-payment] (:due data) + [:schedule-when-due] true]) + + + schedule-payment-dom + (into [[:scheduled-payment] (date->str (next-dom (str->date (:date data) standard) schedule-payment-dom) standard)]) + + true + (into [[:schedule-payment-dom] schedule-payment-dom]))) (= [:total] field) [[:expense-accounts] (recalculate-amounts (:expense-accounts data) value)] + (and (= [:date] field) + (:schedule-payment-dom data)) + [[:scheduled-payment] (date->str (next-dom (str->date value standard) (:schedule-payment-dom data)) standard) ] + (and (= [:schedule-when-due] field) value) [[:scheduled-payment] (:due data)] diff --git a/src/cljs/auto_ap/views/utils.cljs b/src/cljs/auto_ap/views/utils.cljs index 5e857098..85781527 100644 --- a/src/cljs/auto_ap/views/utils.cljs +++ b/src/cljs/auto_ap/views/utils.cljs @@ -90,7 +90,6 @@ (defn dispatch-date-change [event] (fn [e g] - (println e (c/from-date e) (time/from-default-time-zone (c/from-date e)) (date->str (time/from-default-time-zone (c/from-date e)) standard)) (re-frame/dispatch (conj event (if (str/blank? e) e