Daniel O'Connell fee4de5fd5 basic stock
2021-01-24 18:53:47 +01:00

215 lines
6.5 KiB
Clojure

(ns chicken-master.events
(:require
[re-frame.core :as re-frame]
[chicken-master.db :as db]
[chicken-master.time :as time]
;; required for http mocks
[chicken-master.backend-mocks :as mocks]))
(re-frame/reg-event-db ::initialize-db (fn [_ _] db/default-db))
(re-frame/reg-event-db ::hide-modal (fn [db [_ modal]] (assoc-in db [modal :show] nil)))
(re-frame/reg-event-fx
::confirm-action
(fn [_ [_ msg on-confirm-event & params]]
(when (js/confirm msg)
{:fx [[:dispatch (into [on-confirm-event] params)]]})))
(re-frame/reg-event-fx
::remove-order
(fn [_ [_ id]]
{:http {:method :delete
:url "delete-order"
:params {:id id}
:on-success [::process-fetched-days]
:on-fail [::failed-blah]}}))
(re-frame/reg-event-db
::edit-order
(fn [{customers :customers :as db} [_ day id]]
(assoc db :order-edit
(-> customers
(get id {:state :waiting})
(update :products (comp vec (partial map (partial zipmap [:prod :amount]))))
(merge {:show true :day day})))))
(re-frame/reg-event-fx
::fulfill-order
(fn [{db :db} [_ id]]
{:db (assoc-in db [:customers id :state] :pending)
:fx [[:dispatch [::set-current-days]]]
:http {:method :post
:url "fulfill-order"
:params {:id id}
:on-success [::process-fetched-days]
:on-fail [::failed-blah]}}))
(re-frame/reg-event-fx
::reset-order
(fn [{db :db} [_ id]]
{:db (assoc-in db [:customers id :state] :waiting)
:fx [[:dispatch [::set-current-days]]]
:http {:method :post
:url "reset-order"
:params {:id id}
:on-success [::process-fetched-days]
:on-fail [::failed-blah]}}))
(re-frame/reg-event-fx
::save-order
(fn [{{order :order-edit} :db} [_ form]]
{:fx [[:dispatch [::hide-modal :order-edit]]]
:http {:method :post
:url "save-order"
:params (merge
(select-keys order [:id :day :hour :state])
(select-keys form [:who :notes :products]))
:on-success [::process-fetched-days]
:on-fail [::failed-blah]}}))
(re-frame/reg-event-db ::add-product (fn [db _] (update-in db [:order-edit :products] conj {})))
(re-frame/reg-event-db
::selected-product
(fn [db [_ product product-no]]
(assoc-in db [:order-edit :products product-no :prod] product)))
(re-frame/reg-event-db
::changed-amount
(fn [db [_ amount product-no]]
(assoc-in db [:order-edit :products product-no :amount] amount)))
(defn get-day [{:keys [days customers]} date]
{:date date
:customers (->> date
time/iso-date
(get days)
(map customers))})
(re-frame/reg-event-db
::set-current-days
(fn [{start-day :start-date :as db} _]
(->> start-day
time/parse-date
time/start-of-week
(time/days-range 14)
(map (partial get-day db))
(assoc db :current-days))))
(re-frame/reg-event-fx
::process-fetched-days
(fn [{db :db} [_ days]]
(println "fetched days" days)
{:db (-> db
(update :days #(reduce-kv (fn [m k v] (assoc m k (map :id v))) % days))
(update :customers #(reduce (fn [m cust] (assoc m (:id cust) cust)) % (-> days vals flatten))))
:fx [[:dispatch [::set-current-days]]
[:dispatch [::fetch-stock]]]}))
(defn missing-days
"Return a map of missing days to be fetched."
[db day]
(let [missing-days (->> day
time/parse-date
time/start-of-week
(time/days-range 28)
(remove (comp (:days db {}) time/iso-date)))]
(when (seq missing-days)
{:from (->> missing-days (sort time/before?) first time/iso-date)
:to (->> missing-days (sort time/before?) last time/iso-date)})))
(re-frame/reg-event-fx
::scroll-weeks
(fn [{db :db} [_ offset]]
{:fx [[:dispatch [::show-from-date (-> db :start-date time/parse-date (time/date-offset (* 7 offset)))]]]}))
(re-frame/reg-event-fx
::show-from-date
(fn [{db :db} [_ day]]
(let [missing (missing-days db day)
effects {:db (assoc db :start-date day)
:fx [[:dispatch [::set-current-days]]]}]
(if-not missing
effects
(assoc effects :http {:method :get
:url "get-days"
:params missing
:on-success [::process-fetched-days]
:on-fail [::failed-blah]})))))
;;; Storage events
(re-frame/reg-event-fx
::show-stock
(fn [{db :db} _]
{:db (assoc-in db [:stock :show] true)
:fx [[:dispatch [::fetch-stock]]]}))
(re-frame/reg-event-fx
::fetch-stock
(fn [_ _]
{:http {:method :get
:url "get-all-products"
:on-success [::process-stock]
:on-fail [::failed-blah]}}))
(re-frame/reg-event-db
::process-stock
(fn [db [_ stock]]
(println "fetched stock" stock)
(assoc db :products stock)))
(re-frame/reg-event-db
::update-product-stock
(fn [db [_ product i]]
(update-in db [:products product] + i)))
(re-frame/reg-event-db
::set-stock-amount
(fn [db [_ product i]]
(prn i)
(assoc-in db [:products product] i)))
(re-frame/reg-event-db
::set-stock-amount
(fn [db [_ product i]]
(prn i)
(assoc-in db [:products product] i)))
(re-frame/reg-event-fx
::save-stock
(fn [{db :db} [_ products]]
{:fx [[:dispatch [::hide-modal :stock]]]
:http {:method :post
:url "save-stock"
:body products
:on-success [::process-fetched-days]
:on-fail [::failed-blah]}}))
(comment
(re-frame/dispatch-sync [::show-stock])
(re-frame/dispatch-sync [::update-product-stock :eggs 2])
)
;;;;;;;; Backend mocks
(re-frame/reg-fx
:http
(fn [{:keys [method url params body on-success on-fail]}]
(condp = url
"get-days" (re-frame/dispatch (conj on-success (mocks/fetch-days params)))
"save-order" (re-frame/dispatch (conj on-success (mocks/replace-order params)))
"delete-order" (re-frame/dispatch (conj on-success (mocks/delete-order params)))
"fulfill-order" (re-frame/dispatch (conj on-success (mocks/order-state (assoc params :state :fulfilled))))
"reset-order" (re-frame/dispatch (conj on-success (mocks/order-state (assoc params :state :waiting))))
"get-all-products" (re-frame/dispatch (conj on-success (mocks/get-all-products)))
"save-stock" (re-frame/dispatch (conj on-success (mocks/save-stocks body)))
)))