mirror of
https://github.com/mruwnik/chicken-master.git
synced 2025-06-08 21:34:43 +02:00
Backend api
This commit is contained in:
parent
f361882a3f
commit
0f21522a90
11
project.clj
11
project.clj
@ -7,10 +7,13 @@
|
|||||||
[thheller/shadow-cljs "2.11.0"]
|
[thheller/shadow-cljs "2.11.0"]
|
||||||
[reagent "0.10.0"]
|
[reagent "0.10.0"]
|
||||||
[re-frame "1.1.1"]
|
[re-frame "1.1.1"]
|
||||||
|
[day8.re-frame/http-fx "0.2.2"]
|
||||||
[garden "1.3.10"]
|
[garden "1.3.10"]
|
||||||
[ns-tracker "0.4.0"]
|
[ns-tracker "0.4.0"]
|
||||||
[compojure "1.6.2"]
|
[compojure "1.6.2"]
|
||||||
[yogthos/config "1.1.7"]
|
[yogthos/config "1.1.7"]
|
||||||
|
[ring-basic-authentication "1.1.0"]
|
||||||
|
[ring-cors "0.1.13"]
|
||||||
[ring "1.8.1"]]
|
[ring "1.8.1"]]
|
||||||
|
|
||||||
:plugins [[lein-shadow "0.2.2"]
|
:plugins [[lein-shadow "0.2.2"]
|
||||||
@ -34,7 +37,7 @@
|
|||||||
:pretty-print? true}}]}
|
:pretty-print? true}}]}
|
||||||
|
|
||||||
:shadow-cljs {:nrepl {:port 8777}
|
:shadow-cljs {:nrepl {:port 8777}
|
||||||
|
|
||||||
:builds {:app {:target :browser
|
:builds {:app {:target :browser
|
||||||
:output-dir "resources/public/js/compiled"
|
:output-dir "resources/public/js/compiled"
|
||||||
:asset-path "/js/compiled"
|
:asset-path "/js/compiled"
|
||||||
@ -45,14 +48,14 @@
|
|||||||
:http-port 8280
|
:http-port 8280
|
||||||
:http-handler chicken-master.handler/dev-handler
|
:http-handler chicken-master.handler/dev-handler
|
||||||
}}}}
|
}}}}
|
||||||
|
|
||||||
:shell {:commands {"karma" {:windows ["cmd" "/c" "karma"]
|
:shell {:commands {"karma" {:windows ["cmd" "/c" "karma"]
|
||||||
:default-command "karma"}
|
:default-command "karma"}
|
||||||
"open" {:windows ["cmd" "/c" "start"]
|
"open" {:windows ["cmd" "/c" "start"]
|
||||||
:macosx "open"
|
:macosx "open"
|
||||||
:linux "xdg-open"}}}
|
:linux "xdg-open"}}}
|
||||||
|
|
||||||
:aliases {"dev" ["do"
|
:aliases {"dev" ["do"
|
||||||
["shell" "echo" "\"DEPRECATED: Please use lein watch instead.\""]
|
["shell" "echo" "\"DEPRECATED: Please use lein watch instead.\""]
|
||||||
["watch"]]
|
["watch"]]
|
||||||
"watch" ["with-profile" "dev" "do"
|
"watch" ["with-profile" "dev" "do"
|
||||||
@ -82,7 +85,7 @@
|
|||||||
:source-paths ["dev"]}
|
:source-paths ["dev"]}
|
||||||
|
|
||||||
:prod {}
|
:prod {}
|
||||||
|
|
||||||
:uberjar {:source-paths ["env/prod/clj"]
|
:uberjar {:source-paths ["env/prod/clj"]
|
||||||
:omit-source true
|
:omit-source true
|
||||||
:main chicken-master.server
|
:main chicken-master.server
|
||||||
|
@ -1,15 +1,81 @@
|
|||||||
(ns chicken-master.handler
|
(ns chicken-master.handler
|
||||||
(:require
|
(:require [chicken-master.mocks :as mocks]
|
||||||
[compojure.core :refer [GET defroutes]]
|
[clojure.edn :as edn]
|
||||||
[compojure.route :refer [resources]]
|
[compojure.core :refer [GET POST PUT DELETE defroutes]]
|
||||||
[ring.util.response :refer [resource-response]]
|
[compojure.route :refer [resources]]
|
||||||
[ring.middleware.reload :refer [wrap-reload]]
|
[compojure.handler :refer [api]]
|
||||||
[shadow.http.push-state :as push-state]))
|
[ring.util.response :refer [resource-response]]
|
||||||
|
[ring.middleware.basic-authentication :refer [wrap-basic-authentication]]
|
||||||
|
[ring.middleware.cors :refer [wrap-cors]]))
|
||||||
|
|
||||||
|
(defn get-customers [] {:body (mocks/fetch-customers {})})
|
||||||
|
(defn add-customer [request] {:body (some-> request :body :name mocks/add-customer)})
|
||||||
|
|
||||||
|
(defn get-products [_] (prn _){:body (mocks/get-all-products)})
|
||||||
|
(defn save-products [request] {:body (some-> request :body mocks/save-stocks)})
|
||||||
|
|
||||||
|
(defn get-orders [params] {:body {:orders (mocks/get-orders params)}})
|
||||||
|
(defn update-order [request]
|
||||||
|
(let [id (some-> request :route-params :id (Integer/parseInt))
|
||||||
|
body (some->> request :body)]
|
||||||
|
{:body (mocks/replace-order id body)}))
|
||||||
|
|
||||||
|
(defn delete-order [id] {:body (mocks/delete-order (edn/read-string id))})
|
||||||
|
(defn set-order-state [id status] (prn "asd"){:body (mocks/order-state (edn/read-string id) status)})
|
||||||
|
|
||||||
|
(defn get-stock [params]
|
||||||
|
{:body
|
||||||
|
{:customers (:body (get-customers))
|
||||||
|
:products (:body (get-products params))}})
|
||||||
|
|
||||||
(defroutes routes
|
(defroutes routes
|
||||||
|
(GET "/stock" {params :query-params} (get-stock params))
|
||||||
|
(GET "/customers" [] (get-customers))
|
||||||
|
(POST "/customers" request (add-customer request))
|
||||||
|
|
||||||
|
(GET "/products" request (get-products request))
|
||||||
|
(POST "/products" request (save-products request))
|
||||||
|
|
||||||
|
(GET "/orders" {params :query-params} (get-orders params))
|
||||||
|
(POST "/orders" request (update-order request))
|
||||||
|
(PUT "/orders/:id" request (update-order request))
|
||||||
|
(DELETE "/orders/:id" [id] (delete-order id))
|
||||||
|
(POST "/orders/:id/:status" [id status] (set-order-state id status))
|
||||||
|
|
||||||
(GET "/" [] (resource-response "index.html" {:root "public"}))
|
(GET "/" [] (resource-response "index.html" {:root "public"}))
|
||||||
(resources "/"))
|
(resources "/"))
|
||||||
|
|
||||||
(def dev-handler (-> #'routes wrap-reload push-state/handle))
|
|
||||||
|
|
||||||
(def handler routes)
|
(defn- handle-edn [response]
|
||||||
|
(if (string? (:body response))
|
||||||
|
response
|
||||||
|
(-> response
|
||||||
|
(assoc-in [:headers "Content-Type"] "application/edn")
|
||||||
|
(update :body pr-str))))
|
||||||
|
|
||||||
|
(defn wrap-edn-response [handler]
|
||||||
|
(fn
|
||||||
|
([request]
|
||||||
|
(-> request handler handle-edn))
|
||||||
|
([request respond raise]
|
||||||
|
(-> request handler handle-edn respond))))
|
||||||
|
|
||||||
|
(defn wrap-edn-request [handler]
|
||||||
|
(fn
|
||||||
|
([request]
|
||||||
|
(handler
|
||||||
|
(if (= (:content-type request) "application/edn")
|
||||||
|
(update request :body (comp edn/read-string slurp))
|
||||||
|
request)))))
|
||||||
|
|
||||||
|
(defn authenticated? [name pass]
|
||||||
|
(and (= name "siloa")
|
||||||
|
(= pass "krach")))
|
||||||
|
|
||||||
|
(def handler (-> routes
|
||||||
|
(wrap-basic-authentication authenticated?)
|
||||||
|
(wrap-cors :access-control-allow-origin [#"http://localhost:8280"]
|
||||||
|
:access-control-allow-methods [:get :put :post :delete :options])
|
||||||
|
api
|
||||||
|
wrap-edn-request
|
||||||
|
wrap-edn-response))
|
||||||
|
95
src/clj/chicken_master/mocks.clj
Normal file
95
src/clj/chicken_master/mocks.clj
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
(ns chicken-master.mocks
|
||||||
|
(:import [java.time Instant]
|
||||||
|
[java.time.temporal ChronoUnit]))
|
||||||
|
|
||||||
|
|
||||||
|
(defn format-date [d] (-> d str (subs 0 10)))
|
||||||
|
|
||||||
|
(defn days-range [days date ]
|
||||||
|
(map #(.plus date % ChronoUnit/DAYS) (range days)))
|
||||||
|
|
||||||
|
;;;; Stock
|
||||||
|
|
||||||
|
(def stock-products (atom {:eggs 22 :milk 32 :cabbage 54 :carrots 11 :cows 32 :ants 21}))
|
||||||
|
|
||||||
|
(defn get-all-products [] @stock-products)
|
||||||
|
(defn save-stocks [new-products] (reset! stock-products new-products))
|
||||||
|
|
||||||
|
;;; Orders
|
||||||
|
|
||||||
|
(def id-counter (atom -1))
|
||||||
|
(def notes ["bezglutenowy"
|
||||||
|
"tylko z robakami"
|
||||||
|
"przyjdzie wieczorem"
|
||||||
|
"wisi 2.50"
|
||||||
|
"chciała ukraść kozę"])
|
||||||
|
(def products (atom [:eggs :milk :cabbage :carrots]))
|
||||||
|
(def customers (atom [{:id 1 :name "mr.blobby (649 234 234)"}
|
||||||
|
{:id 2 :name "da police (0118 999 881 999 119 725 123123 12 3123 123 )"}
|
||||||
|
{:id 3 :name "johnny"}]))
|
||||||
|
(def orders
|
||||||
|
(atom
|
||||||
|
(->> (-> (Instant/now) (.minus 50 ChronoUnit/DAYS))
|
||||||
|
(days-range 90)
|
||||||
|
(map (fn [date]
|
||||||
|
[(format-date date) (repeatedly (rand-int 6) #(swap! id-counter inc))]))
|
||||||
|
(map (fn [[day ids]]
|
||||||
|
(map (fn [i]
|
||||||
|
{:id i :day day
|
||||||
|
:notes (when (> (rand) 0.7) (rand-nth notes))
|
||||||
|
:state :waiting
|
||||||
|
:who (rand-nth @customers)
|
||||||
|
:products (->> @products
|
||||||
|
(random-sample 0.4)
|
||||||
|
(map #(vector % (rand-int 10)))
|
||||||
|
(into {}))
|
||||||
|
}) ids)
|
||||||
|
))
|
||||||
|
flatten
|
||||||
|
(map #(vector (:id %) %))
|
||||||
|
(into {}))))
|
||||||
|
|
||||||
|
|
||||||
|
(defn fetch-customers [_]
|
||||||
|
@customers)
|
||||||
|
|
||||||
|
(defn fetch-stock [params]
|
||||||
|
{:customers (fetch-customers params)
|
||||||
|
:products (get-all-products)})
|
||||||
|
|
||||||
|
(defn add-customer [customer-name]
|
||||||
|
(swap! customers conj {:id (->> @customers (map :id) (apply max) inc)
|
||||||
|
:name customer-name})
|
||||||
|
(fetch-stock {}))
|
||||||
|
|
||||||
|
(defn day-customers [day] [day (->> @orders vals (filter (comp #{day} :day)))])
|
||||||
|
|
||||||
|
(defn get-orders [params] @orders)
|
||||||
|
|
||||||
|
(defn replace-order [id order]
|
||||||
|
(println "replacing order" order)
|
||||||
|
(let [prev-day (:day (@orders (:id order)))
|
||||||
|
order (update order :id #(or % (swap! id-counter inc)))]
|
||||||
|
(prn "order 1" order)
|
||||||
|
(swap! orders assoc (:id order) order)
|
||||||
|
(prn "order 2" (@orders (:id order)))
|
||||||
|
(if (or (not prev-day) (= prev-day (:day order)))
|
||||||
|
{(:day order) (->> order :day day-customers second)}
|
||||||
|
{prev-day (->> prev-day day-customers second)
|
||||||
|
(:day order) (->> order :day day-customers second)})))
|
||||||
|
|
||||||
|
(defn delete-order [id]
|
||||||
|
(println "deleting order" id)
|
||||||
|
(let [day (-> (get @orders id) :day)]
|
||||||
|
(swap! orders #(dissoc % id))
|
||||||
|
{day (->> day day-customers second)}))
|
||||||
|
|
||||||
|
(defn order-state [id state]
|
||||||
|
(prn "fulfilling order" id state)
|
||||||
|
(condp = state
|
||||||
|
"fulfilled" (->> id (get @orders) :products (swap! stock-products #(merge-with - %1 %2)))
|
||||||
|
"waiting" (->> id (get @orders) :products (swap! stock-products #(merge-with + %1 %2))))
|
||||||
|
(let [day (-> (get @orders id) :day)]
|
||||||
|
(swap! orders #(assoc-in % [id :state] (keyword state)))
|
||||||
|
(println id (get @orders id))
|
||||||
|
{day (->> day day-customers second)}))
|
@ -7,3 +7,8 @@
|
|||||||
(defn -main [& _args]
|
(defn -main [& _args]
|
||||||
(let [port (or (env :port) 3000)]
|
(let [port (or (env :port) 3000)]
|
||||||
(run-jetty handler {:port port :join? false})))
|
(run-jetty handler {:port port :join? false})))
|
||||||
|
|
||||||
|
(def h
|
||||||
|
(let [port (or (env :port) 3000)]
|
||||||
|
(run-jetty handler {:port port :join? false})))
|
||||||
|
(.stop h)
|
||||||
|
@ -6,17 +6,12 @@
|
|||||||
(def stock-products (atom {:eggs 22 :milk 32 :cabbage 54 :carrots 11 :cows 32 :ants 21}))
|
(def stock-products (atom {:eggs 22 :milk 32 :cabbage 54 :carrots 11 :cows 32 :ants 21}))
|
||||||
|
|
||||||
(defn get-all-products [] @stock-products)
|
(defn get-all-products [] @stock-products)
|
||||||
(defn save-stocks [new-products] (reset! stock-products new-products))
|
(defn save-stocks [new-products]
|
||||||
|
(reset! stock-products new-products))
|
||||||
|
|
||||||
;;; Orders
|
;;; Orders
|
||||||
|
|
||||||
(def id-counter (atom -1))
|
(def id-counter (atom -1))
|
||||||
;; (def days (atom
|
|
||||||
;; (->> (time/date-offset (new js/Date) -50)
|
|
||||||
;; (time/days-range 90)
|
|
||||||
;; (map (fn [date]
|
|
||||||
;; [(time/iso-date date) (repeatedly (rand-int 6) #(swap! id-counter inc))]))
|
|
||||||
;; (into {}))))
|
|
||||||
(def notes ["bezglutenowy"
|
(def notes ["bezglutenowy"
|
||||||
"tylko z robakami"
|
"tylko z robakami"
|
||||||
"przyjdzie wieczorem"
|
"przyjdzie wieczorem"
|
||||||
@ -56,9 +51,11 @@
|
|||||||
{:customers (fetch-customers params)
|
{:customers (fetch-customers params)
|
||||||
:products (get-all-products)})
|
:products (get-all-products)})
|
||||||
|
|
||||||
(defn add-customer [{:keys [customer-name] :as params}]
|
(defn add-customer [{:keys [name] :as params}]
|
||||||
|
(prn name)
|
||||||
(swap! customers conj {:id (->> @customers (map :id) (apply max) inc)
|
(swap! customers conj {:id (->> @customers (map :id) (apply max) inc)
|
||||||
:name customer-name})
|
:name name})
|
||||||
|
(prn @customers)
|
||||||
(fetch-stock params))
|
(fetch-stock params))
|
||||||
|
|
||||||
(defn- day-customers [day] [day (->> @orders vals (filter (comp #{day} :day)))])
|
(defn- day-customers [day] [day (->> @orders vals (filter (comp #{day} :day)))])
|
||||||
@ -67,31 +64,21 @@
|
|||||||
(int (/ (- (time/parse-date to) (time/parse-date from)) (* 24 3600000)))
|
(int (/ (- (time/parse-date to) (time/parse-date from)) (* 24 3600000)))
|
||||||
(time/parse-date from)))
|
(time/parse-date from)))
|
||||||
|
|
||||||
(defn fetch-days [{:keys [from to]}]
|
(defn fetch-orders [{:keys [from to]}]
|
||||||
(->> (days-between from to)
|
{:orders @orders})
|
||||||
(map time/iso-date)
|
|
||||||
(map day-customers)
|
|
||||||
(into {})))
|
|
||||||
|
|
||||||
(defn- replace-order [{start-from :start-from :as order}]
|
(defn- replace-order [id order]
|
||||||
(println "replacing order" order)
|
(println "replacing order" order)
|
||||||
(let [order (-> order
|
(let [prev-day (:day (get @orders id))
|
||||||
(dissoc :start-from)
|
order (update order :id #(or % (swap! id-counter inc)))]
|
||||||
(update :id #(or % (swap! id-counter inc))))]
|
|
||||||
(prn "order 1" order)
|
|
||||||
(swap! orders assoc (:id order) order)
|
(swap! orders assoc (:id order) order)
|
||||||
(prn "order 2" (@orders (:id order)))
|
(if prev-day
|
||||||
(if start-from
|
{prev-day (->> prev-day day-customers second)
|
||||||
(->> start-from
|
(:day order) (->> order :day day-customers second)}
|
||||||
time/start-of-week
|
|
||||||
(time/days-range 28)
|
|
||||||
(map time/iso-date)
|
|
||||||
(map day-customers)
|
|
||||||
(into {}))
|
|
||||||
{(:day order) (->> order :day day-customers second)})))
|
{(:day order) (->> order :day day-customers second)})))
|
||||||
|
|
||||||
(defn- delete-order [{id :id}]
|
(defn- delete-order [id]
|
||||||
(println "deleting order" id)
|
(println "deleting order" id (get @orders id))
|
||||||
(let [day (-> (get @orders id) :day)]
|
(let [day (-> (get @orders id) :day)]
|
||||||
(swap! orders #(dissoc % id))
|
(swap! orders #(dissoc % id))
|
||||||
{day (->> day day-customers second)}))
|
{day (->> day day-customers second)}))
|
||||||
|
@ -51,13 +51,13 @@
|
|||||||
(map prod/format-product)
|
(map prod/format-product)
|
||||||
(into [:div {:class :products}]))])
|
(into [:div {:class :products}]))])
|
||||||
|
|
||||||
(defn day [{:keys [date orders]}]
|
(defn day [[date orders]]
|
||||||
[:div {:class [:day (when (time/today? date) :today)]
|
[:div {:class [:day (when (-> date time/parse-date time/today?) :today)]
|
||||||
:on-drag-over #(.preventDefault %)
|
:on-drag-over #(.preventDefault %)
|
||||||
:on-drop #(let [id (-> % .-dataTransfer (.getData "text") prod/num-or-nil)]
|
:on-drop #(let [id (-> % .-dataTransfer (.getData "text") prod/num-or-nil)]
|
||||||
(.preventDefault %)
|
(.preventDefault %)
|
||||||
(re-frame/dispatch [::event/move-order id (time/iso-date date)]))}
|
(re-frame/dispatch [::event/move-order id date]))}
|
||||||
[:div {:class :day-header} (time/format-date date)]
|
[:div {:class :day-header} (-> date time/parse-date time/format-date)]
|
||||||
[:div
|
[:div
|
||||||
[:div {:class :orders}
|
[:div {:class :orders}
|
||||||
(if (settings :hide-fulfilled-orders)
|
(if (settings :hide-fulfilled-orders)
|
||||||
@ -65,7 +65,7 @@
|
|||||||
(map format-order orders))
|
(map format-order orders))
|
||||||
(when (settings :show-day-add-order)
|
(when (settings :show-day-add-order)
|
||||||
[:button {:type :button
|
[:button {:type :button
|
||||||
:on-click #(re-frame/dispatch [::event/edit-order (time/iso-date date)])} "+"])
|
:on-click #(re-frame/dispatch [::event/edit-order date])} "+"])
|
||||||
(when (seq (map :products orders))
|
(when (seq (map :products orders))
|
||||||
[:div {:class :summary}
|
[:div {:class :summary}
|
||||||
[:hr {:class :day-seperator}]
|
[:hr {:class :day-seperator}]
|
||||||
@ -75,8 +75,7 @@
|
|||||||
(apply merge-with +)
|
(apply merge-with +)
|
||||||
(sort-by first)
|
(sort-by first)
|
||||||
(map prod/format-product)
|
(map prod/format-product)
|
||||||
(into [:div {:class :products-sum}]))])
|
(into [:div {:class :products-sum}]))])]]])
|
||||||
]]])
|
|
||||||
|
|
||||||
(defn calendar-header []
|
(defn calendar-header []
|
||||||
(->> (:day-names settings)
|
(->> (:day-names settings)
|
||||||
|
@ -14,4 +14,7 @@
|
|||||||
:show-order-notes true ; display notes
|
:show-order-notes true ; display notes
|
||||||
:editable-number-inputs false ; only allow number modifications in the edit modal
|
:editable-number-inputs false ; only allow number modifications in the edit modal
|
||||||
:hide-fulfilled-orders false
|
:hide-fulfilled-orders false
|
||||||
|
|
||||||
|
:http-dispatch :http;-xhrio
|
||||||
|
:backend-url "http://localhost:3000/"
|
||||||
})
|
})
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
(defn order-adder [order]
|
(defn order-adder [order]
|
||||||
(let [state (reagent/atom order)]
|
(let [state (reagent/atom order)]
|
||||||
(fn []
|
(fn []
|
||||||
[:details {:class :customer-order :key (gensym) :open (:open @state)}
|
[:details {:class (or (:class order) :customer-order) :key (gensym) :open (:open @state)}
|
||||||
[:summary {:on-click #(swap! state update :open not)}
|
[:summary {:on-click #(swap! state update :open not)}
|
||||||
[prod/item-adder
|
[prod/item-adder
|
||||||
:type :date
|
:type :date
|
||||||
@ -34,8 +34,8 @@
|
|||||||
(for [{:keys [name id] :as who} @(re-frame/subscribe [::subs/available-customers])]
|
(for [{:keys [name id] :as who} @(re-frame/subscribe [::subs/available-customers])]
|
||||||
[:details {:class "client" :key (gensym)}
|
[:details {:class "client" :key (gensym)}
|
||||||
[:summary name]
|
[:summary name]
|
||||||
(for [order (sort-by :day (client-orders id))]
|
[order-adder {:who who}]
|
||||||
|
(for [order (reverse (sort-by :day (client-orders id)))]
|
||||||
[order-adder (assoc order :key (gensym))])
|
[order-adder (assoc order :key (gensym))])
|
||||||
[order-adder who :class :new-user]
|
|
||||||
]))]
|
]))]
|
||||||
))
|
))
|
||||||
|
@ -3,20 +3,40 @@
|
|||||||
[re-frame.core :as re-frame]
|
[re-frame.core :as re-frame]
|
||||||
[chicken-master.db :as db]
|
[chicken-master.db :as db]
|
||||||
[chicken-master.time :as time]
|
[chicken-master.time :as time]
|
||||||
|
[chicken-master.config :refer [settings]]
|
||||||
|
[day8.re-frame.http-fx]
|
||||||
|
[ajax.edn :as edn]
|
||||||
|
|
||||||
;; required for http mocks
|
;; required for http mocks
|
||||||
[chicken-master.backend-mocks :as mocks]))
|
[chicken-master.backend-mocks :as mocks]))
|
||||||
|
|
||||||
|
(defn http-request [method endpoint & {:keys [params body on-success on-failure]
|
||||||
|
:or {on-success ::process-fetched-days
|
||||||
|
on-failure ::failed-blah}}]
|
||||||
|
{:method method
|
||||||
|
:uri (str (settings :backend-url) endpoint)
|
||||||
|
:headers {"Content-Type" "application/edn"
|
||||||
|
"authorization" "Basic c2lsb2E6a3JhY2g="}
|
||||||
|
:format (edn/edn-request-format)
|
||||||
|
:body (some-> body pr-str)
|
||||||
|
:params params
|
||||||
|
:response-format (edn/edn-response-format)
|
||||||
|
:on-success [on-success]
|
||||||
|
:on-fail [on-failure]})
|
||||||
|
|
||||||
|
(defn http-get [endpoint params on-success]
|
||||||
|
(http-request :get endpoint :params params :on-success on-success))
|
||||||
|
|
||||||
|
(defn http-post [endpoint body]
|
||||||
|
(http-request :post endpoint :body body))
|
||||||
|
|
||||||
(re-frame/reg-event-fx
|
(re-frame/reg-event-fx
|
||||||
::initialize-db
|
::initialize-db
|
||||||
(fn [_ _]
|
(fn [_ _]
|
||||||
{:db db/default-db
|
{:db db/default-db
|
||||||
:dispatch [::show-from-date (new js/Date)]
|
:fx [[:dispatch [::show-from-date (time/iso-date (time/today))]]
|
||||||
:http {:method :post
|
[:dispatch [::fetch-stock]]
|
||||||
:url "get-stock"
|
[:dispatch [::fetch-orders]]]}))
|
||||||
:params {}
|
|
||||||
:on-success [::process-stock]
|
|
||||||
:on-fail [::failed-blah]}}))
|
|
||||||
|
|
||||||
(re-frame/reg-event-db ::hide-modal (fn [db [_ modal]] (assoc-in db [modal :show] nil)))
|
(re-frame/reg-event-db ::hide-modal (fn [db [_ modal]] (assoc-in db [modal :show] nil)))
|
||||||
|
|
||||||
@ -29,20 +49,14 @@
|
|||||||
(re-frame/reg-event-fx
|
(re-frame/reg-event-fx
|
||||||
::remove-order
|
::remove-order
|
||||||
(fn [_ [_ id]]
|
(fn [_ [_ id]]
|
||||||
{:http {:method :delete
|
{(settings :http-dispatch) (http-request :delete (str "orders/" id))}))
|
||||||
:url "delete-order"
|
|
||||||
:params {:id id}
|
|
||||||
:on-success [::process-fetched-days]
|
|
||||||
:on-fail [::failed-blah]}}))
|
|
||||||
|
|
||||||
(re-frame/reg-event-fx
|
(re-frame/reg-event-fx
|
||||||
::move-order
|
::move-order
|
||||||
(fn [{{orders :orders start-date :start-date} :db} [_ id day]]
|
(fn [{{orders :orders start-date :start-date} :db} [_ id day]]
|
||||||
{:http {:method :post
|
{(settings :http-dispatch)
|
||||||
:url "save-order"
|
(http-request :put (str "orders/" id)
|
||||||
:params (-> id orders (assoc :day day :start-from start-date))
|
:body (-> id orders (assoc :day day :start-from start-date)))}))
|
||||||
:on-success [::process-fetched-days]
|
|
||||||
:on-fail [::failed-blah]}}))
|
|
||||||
|
|
||||||
(re-frame/reg-event-db
|
(re-frame/reg-event-db
|
||||||
::edit-order
|
::edit-order
|
||||||
@ -56,107 +70,57 @@
|
|||||||
::fulfill-order
|
::fulfill-order
|
||||||
(fn [{db :db} [_ id]]
|
(fn [{db :db} [_ id]]
|
||||||
{:db (assoc-in db [:orders id :state] :pending)
|
{:db (assoc-in db [:orders id :state] :pending)
|
||||||
:dispatch [::set-current-days]
|
(settings :http-dispatch) (http-request :post (str "orders/" id "/fulfilled"))}))
|
||||||
:http {:method :post
|
|
||||||
:url "fulfill-order"
|
|
||||||
:params {:id id}
|
|
||||||
:on-success [::process-fetched-days]
|
|
||||||
:on-fail [::failed-blah]}}))
|
|
||||||
|
|
||||||
(re-frame/reg-event-fx
|
(re-frame/reg-event-fx
|
||||||
::reset-order
|
::reset-order
|
||||||
(fn [{db :db} [_ id]]
|
(fn [{db :db} [_ id]]
|
||||||
{:db (assoc-in db [:orders id :state] :waiting)
|
{:db (assoc-in db [:orders id :state] :waiting)
|
||||||
:fx [[:dispatch [::set-current-days]]]
|
(settings :http-dispatch) (http-request :post (str "orders/" id "/waiting"))}))
|
||||||
:http {:method :post
|
|
||||||
:url "reset-order"
|
|
||||||
:params {:id id}
|
|
||||||
:on-success [::process-fetched-days]
|
|
||||||
:on-fail [::failed-blah]}}))
|
|
||||||
|
|
||||||
(re-frame/reg-event-fx
|
(re-frame/reg-event-fx
|
||||||
::save-order
|
::save-order
|
||||||
(fn [{{order :order-edit} :db} [_ form]]
|
(fn [{{order :order-edit} :db} [_ form]]
|
||||||
{:dispatch [::hide-modal :order-edit]
|
{:dispatch [::hide-modal :order-edit]
|
||||||
:http {:method :post
|
(settings :http-dispatch) (http-post (str "orders")
|
||||||
:url "save-order"
|
(merge
|
||||||
:params (merge
|
(select-keys order [:id :day :hour :state])
|
||||||
(select-keys order [:id :day :hour :state])
|
(select-keys form [:id :day :hour :state :who :notes :products])))}))
|
||||||
(select-keys form [:id :day :hour :state :who :notes :products]))
|
|
||||||
:on-success [::process-fetched-days]
|
|
||||||
:on-fail [::failed-blah]}}))
|
|
||||||
|
|
||||||
(re-frame/reg-event-db
|
(re-frame/reg-event-db
|
||||||
::selected-product
|
|
||||||
(fn [db [_ product product-no]]
|
|
||||||
(let [db (assoc-in db [:order-edit :products product-no :prod] product)]
|
|
||||||
(if (-> db :order-edit :products last :prod)
|
|
||||||
(update-in db [:order-edit :products] conj {})
|
|
||||||
db))))
|
|
||||||
(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 orders]} date]
|
|
||||||
{:date date
|
|
||||||
:orders (->> date
|
|
||||||
time/iso-date
|
|
||||||
(get days)
|
|
||||||
(map orders))})
|
|
||||||
|
|
||||||
(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
|
::process-fetched-days
|
||||||
(fn [{db :db} [_ days]]
|
(fn [db [_ days]]
|
||||||
(println "fetched days" days)
|
(-> db
|
||||||
{:db (-> db
|
(update :current-days #(map (fn [[day orders]]
|
||||||
(update :days #(reduce-kv (fn [m k v] (assoc m k (map :id v))) % days))
|
[day (if (contains? days day)
|
||||||
(update :orders #(reduce (fn [m cust] (assoc m (:id cust) cust)) % (-> days vals flatten))))
|
(days day) orders)]) %))
|
||||||
:fx [[:dispatch [::set-current-days]]
|
(update :orders #(reduce (fn [m cust] (assoc m (:id cust) cust)) % (-> days vals flatten))))))
|
||||||
[: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
|
(re-frame/reg-event-fx
|
||||||
::scroll-weeks
|
::scroll-weeks
|
||||||
(fn [{db :db} [_ offset]]
|
(fn [{db :db} [_ offset]]
|
||||||
{:dispatch [::show-from-date (-> db :start-date time/parse-date (time/date-offset (* 7 offset)))]}))
|
{:fx [[:dispatch [::fetch-stock]]
|
||||||
|
[:dispatch [::show-from-date (-> db
|
||||||
|
:start-date
|
||||||
|
time/parse-date
|
||||||
|
(time/date-offset (* 7 offset))
|
||||||
|
time/iso-date)]]]}))
|
||||||
|
|
||||||
|
(re-frame/reg-event-db
|
||||||
|
::show-from-date
|
||||||
|
(fn [{:keys [start-date orders] :as db} [_ day]]
|
||||||
|
(let [day (or day start-date)
|
||||||
|
days (into #{} (time/get-weeks day 2))
|
||||||
|
filtered-orders (->> orders vals (filter days))]
|
||||||
|
(assoc db
|
||||||
|
:start-date day
|
||||||
|
:current-days (map #(vector % (get filtered-orders %)) days)))))
|
||||||
|
|
||||||
(re-frame/reg-event-fx
|
(re-frame/reg-event-fx
|
||||||
::show-from-date
|
::fetch-orders
|
||||||
(fn [{db :db} [_ day]]
|
(fn [_ [_ from to]]
|
||||||
(let [missing (missing-days db day)
|
{(settings :http-dispatch) (http-get "orders" {} ::process-stock)}))
|
||||||
effects {:db (assoc db :start-date day)
|
|
||||||
: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]})))))
|
|
||||||
;; Customers events
|
;; Customers events
|
||||||
(re-frame/reg-event-fx
|
(re-frame/reg-event-fx
|
||||||
::show-customers
|
::show-customers
|
||||||
@ -167,11 +131,9 @@
|
|||||||
(re-frame/reg-event-fx
|
(re-frame/reg-event-fx
|
||||||
::add-customer
|
::add-customer
|
||||||
(fn [_ [_ customer-name]]
|
(fn [_ [_ customer-name]]
|
||||||
{:http {:method :post
|
{(settings :http-dispatch) (http-request :post "customers"
|
||||||
:url "add-customer"
|
:body {:name customer-name}
|
||||||
:params {:customer-name customer-name}
|
:on-success ::process-stock)}))
|
||||||
:on-success [::process-stock]
|
|
||||||
:on-fail [::failed-blah]}}))
|
|
||||||
|
|
||||||
;;; Storage events
|
;;; Storage events
|
||||||
|
|
||||||
@ -184,18 +146,19 @@
|
|||||||
(re-frame/reg-event-fx
|
(re-frame/reg-event-fx
|
||||||
::fetch-stock
|
::fetch-stock
|
||||||
(fn [_ _]
|
(fn [_ _]
|
||||||
{:http {:method :get
|
{(settings :http-dispatch) (http-get "stock" {} ::process-stock)}))
|
||||||
:url "get-stock"
|
|
||||||
:on-success [::process-stock]
|
|
||||||
:on-fail [::failed-blah]}}))
|
|
||||||
|
|
||||||
(re-frame/reg-event-db
|
(defn assoc-if [coll key val] (if val (assoc coll key val) coll))
|
||||||
|
(re-frame/reg-event-fx
|
||||||
::process-stock
|
::process-stock
|
||||||
(fn [db [_ {:keys [products customers]}]]
|
(fn [{db :db} [_ {:keys [products customers orders]}]]
|
||||||
(println "fetched stock" products)
|
(prn products customers orders)
|
||||||
(assoc db
|
{:db (-> db
|
||||||
:products products
|
(assoc-if :products products)
|
||||||
:customers customers)))
|
(assoc-if :customers customers)
|
||||||
|
(assoc-if :orders orders))
|
||||||
|
:dispatch [::process-fetched-days (group-by :day (vals orders))]
|
||||||
|
}))
|
||||||
|
|
||||||
(re-frame/reg-event-db
|
(re-frame/reg-event-db
|
||||||
::update-product-stock
|
::update-product-stock
|
||||||
@ -215,13 +178,9 @@
|
|||||||
|
|
||||||
(re-frame/reg-event-fx
|
(re-frame/reg-event-fx
|
||||||
::save-stock
|
::save-stock
|
||||||
(fn [{db :db} [_ products]]
|
(fn [_ [_ products]]
|
||||||
{:dispatch [::hide-modal :stock]
|
{:dispatch [::hide-modal :stock]
|
||||||
:http {:method :post
|
(settings :http-dispatch) (http-request :post "products" :body products :on-sucess ::process-stock)}))
|
||||||
:url "save-stock"
|
|
||||||
:body products
|
|
||||||
:on-success [::process-fetched-days]
|
|
||||||
:on-fail [::failed-blah]}}))
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -236,17 +195,33 @@
|
|||||||
|
|
||||||
(re-frame/reg-fx
|
(re-frame/reg-fx
|
||||||
:http
|
:http
|
||||||
(fn [{:keys [method url params body on-success on-fail]}]
|
(fn [{:keys [method uri params body on-success on-fail]}]
|
||||||
(condp = url
|
(condp = uri
|
||||||
"get-days" (re-frame/dispatch (conj on-success (mocks/fetch-days params)))
|
"http://localhost:3000/stock" (re-frame/dispatch (conj on-success (mocks/fetch-stock 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-stock" (re-frame/dispatch (conj on-success (mocks/fetch-stock params)))
|
|
||||||
"get-customers" (re-frame/dispatch (conj on-success (mocks/fetch-customers params)))
|
"get-customers" (re-frame/dispatch (conj on-success (mocks/fetch-customers params)))
|
||||||
"add-customer" (re-frame/dispatch (conj on-success (mocks/add-customer params)))
|
"add-customer" (re-frame/dispatch (conj on-success (mocks/add-customer params)))
|
||||||
"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)))
|
"save-stock" (re-frame/dispatch (conj on-success (mocks/save-stocks body)))
|
||||||
|
(let [parts (clojure.string/split uri "/")]
|
||||||
|
(cond
|
||||||
|
(and (= method :get) (= uri "http://localhost:3000/orders"))
|
||||||
|
(re-frame/dispatch (conj on-success (mocks/fetch-orders params)))
|
||||||
|
|
||||||
|
(and (= method :post) (= uri "http://localhost:3000/orders"))
|
||||||
|
(re-frame/dispatch (conj on-success (mocks/replace-order nil (cljs.reader/read-string body))))
|
||||||
|
|
||||||
|
(and (= method :post) (= uri "http://localhost:3000/products"))
|
||||||
|
(re-frame/dispatch (conj on-success (mocks/save-stocks (cljs.reader/read-string body))))
|
||||||
|
|
||||||
|
(= method :delete)
|
||||||
|
(re-frame/dispatch (conj on-success (mocks/delete-order (-> parts (nth 4) (js/parseInt)))))
|
||||||
|
|
||||||
|
|
||||||
|
(and (= method :post) (= uri "http://localhost:3000/customers"))
|
||||||
|
(re-frame/dispatch (conj on-success (mocks/add-customer (cljs.reader/read-string body))))
|
||||||
|
|
||||||
|
(-> parts last #{"fulfilled" "waiting"})
|
||||||
|
(re-frame/dispatch (conj on-success (mocks/order-state {:id (-> parts (nth 4) (js/parseInt)) :state (keyword (last parts))})))
|
||||||
|
true (prn "unhandled" method uri)
|
||||||
|
))
|
||||||
)))
|
)))
|
||||||
|
@ -34,15 +34,16 @@
|
|||||||
|
|
||||||
(defn modal
|
(defn modal
|
||||||
([modal-id content]
|
([modal-id content]
|
||||||
[:div {:class :popup}
|
[:div {:class :popup :on-click #(re-frame/dispatch [::event/hide-modal modal-id])}
|
||||||
[:div {:class :popup-content}
|
[:div {:class :popup-content :on-click #(.stopPropagation %)}
|
||||||
content
|
content
|
||||||
[:div {:class :form-buttons}
|
[:div {:class :form-buttons}
|
||||||
[:button {:type :button :on-click #(re-frame/dispatch [::event/hide-modal modal-id])} "ok"]]]])
|
[:button {:type :button :on-click #(re-frame/dispatch [::event/hide-modal modal-id])} "ok"]]]])
|
||||||
([modal-id content on-submit]
|
([modal-id content on-submit]
|
||||||
[:div {:class :popup}
|
[:div {:class :popup :on-click #(re-frame/dispatch [::event/hide-modal modal-id])}
|
||||||
[:form {:action "#"
|
[:form {:action "#"
|
||||||
:class :popup-content
|
:class :popup-content
|
||||||
|
:on-click #(.stopPropagation %)
|
||||||
:on-submit (fn [e]
|
:on-submit (fn [e]
|
||||||
(.preventDefault e)
|
(.preventDefault e)
|
||||||
(when (-> e .-target form-values on-submit)
|
(when (-> e .-target form-values on-submit)
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
(re-frame/reg-sub ::show-stock-modal (fn [db] (-> db :stock :show)))
|
(re-frame/reg-sub ::show-stock-modal (fn [db] (-> db :stock :show)))
|
||||||
(re-frame/reg-sub ::show-customers-modal (fn [db] (-> db :clients :show)))
|
(re-frame/reg-sub ::show-customers-modal (fn [db] (-> db :clients :show)))
|
||||||
|
|
||||||
(re-frame/reg-sub ::order-edit-who (fn [db] (println (:order-edit db)) (-> db :order-edit :who)))
|
(re-frame/reg-sub ::order-edit-who (fn [db] (-> db :order-edit :who)))
|
||||||
(re-frame/reg-sub ::order-edit-notes (fn [db] (-> db :order-edit :notes)))
|
(re-frame/reg-sub ::order-edit-notes (fn [db] (-> db :order-edit :notes)))
|
||||||
(re-frame/reg-sub ::order-edit-products (fn [db] (-> db :order-edit :products)))
|
(re-frame/reg-sub ::order-edit-products (fn [db] (-> db :order-edit :products)))
|
||||||
|
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
(:require [chicken-master.config :refer [settings]])
|
(:require [chicken-master.config :refer [settings]])
|
||||||
(:import [goog.date DateTime Date Interval]))
|
(:import [goog.date DateTime Date Interval]))
|
||||||
|
|
||||||
|
(defn today [] (new Date))
|
||||||
|
|
||||||
(defn parse-date [date] (new Date (js/Date. date)))
|
(defn parse-date [date] (new Date (js/Date. date)))
|
||||||
|
|
||||||
(defn date-offset
|
(defn date-offset
|
||||||
@ -42,6 +44,13 @@
|
|||||||
|
|
||||||
(defn iso-date [date] (.toIsoString ^js/goog.date.Date date true))
|
(defn iso-date [date] (.toIsoString ^js/goog.date.Date date true))
|
||||||
|
|
||||||
|
(defn get-weeks [from n]
|
||||||
|
(->> from
|
||||||
|
parse-date
|
||||||
|
start-of-week
|
||||||
|
(days-range (* 7 n))
|
||||||
|
(map iso-date)))
|
||||||
|
|
||||||
|
|
||||||
(comment
|
(comment
|
||||||
(with-redefs [settings {:first-day-offset 0}]
|
(with-redefs [settings {:first-day-offset 0}]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user