mirror of
https://github.com/mruwnik/chicken-master.git
synced 2025-06-08 13:24:42 +02:00
add clients view
This commit is contained in:
parent
731dd8ce99
commit
95f0af672f
@ -20,7 +20,7 @@
|
||||
:overflow :auto
|
||||
:z-index 1
|
||||
:background-color "rgba(0,0,0,0.4)"}
|
||||
[:form {
|
||||
[:.popup-content {
|
||||
:background-color "#fefefe"
|
||||
:margin "15% auto"
|
||||
:padding "20px"
|
||||
@ -30,7 +30,7 @@
|
||||
[:.input-item
|
||||
[:label {:min-width "60px"
|
||||
:display :inline-block}]]
|
||||
[:.form-buttons {:margin "10px"}
|
||||
[:..popup-form-buttons {:margin "10px"}
|
||||
[:* {:margin "20px"}]]]]
|
||||
|
||||
[:.scroll-button {:display :none}]
|
||||
@ -41,7 +41,7 @@
|
||||
:font-size "3em"
|
||||
:display :inherit}]
|
||||
[:.popup
|
||||
[:form {
|
||||
[:.popup-content {
|
||||
:background-color "#fefefe"
|
||||
:margin "3% auto"
|
||||
:padding "20px"
|
||||
@ -56,7 +56,7 @@
|
||||
(at-media
|
||||
{:min-width "800px"}
|
||||
[:.popup
|
||||
[:form {
|
||||
[:.popup-content {
|
||||
:background-color "#fefefe"
|
||||
:margin "15% auto"
|
||||
:padding "20px"
|
||||
@ -122,6 +122,12 @@
|
||||
[:label {:display :none}]]
|
||||
]]
|
||||
]
|
||||
|
||||
[:.customers-modal
|
||||
[:details.customer-order {:margin-left "1em" :padding "0.5em"}
|
||||
[:.order-date-picker {:display :inline-block :width "75%" :cursor :pointer}]
|
||||
[:.product-item-edit {:margin-left "1em"}]]]
|
||||
|
||||
]]
|
||||
|
||||
; Chrome, Safari, Edge, Opera
|
||||
|
@ -23,9 +23,10 @@
|
||||
"wisi 2.50"
|
||||
"chciała ukraść kozę"])
|
||||
(def products (atom [:eggs :milk :cabbage :carrots]))
|
||||
(def customer-names (atom ["mr.blobby (649 234 234)" "da police (0118 999 881 999 119 725 123123 12 3123 123 )" "johnny"]))
|
||||
|
||||
(def customers
|
||||
(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
|
||||
(->> @days
|
||||
(map (fn [[day ids]]
|
||||
@ -33,7 +34,7 @@
|
||||
{:id i :day day
|
||||
:notes (when (> (rand) 0.7) (rand-nth notes))
|
||||
:state :waiting
|
||||
:who (rand-nth @customer-names)
|
||||
:who (rand-nth @customers)
|
||||
:products (->> @products
|
||||
(random-sample 0.4)
|
||||
(map #(vector % (rand-int 10)))
|
||||
@ -44,13 +45,25 @@
|
||||
(map #(vector (:id %) %))
|
||||
(into {}))))
|
||||
|
||||
(defn- day-customers [day] [day (->> day (get @days) (map (partial get @customers)))])
|
||||
|
||||
(defn fetch-customers [_]
|
||||
@customers)
|
||||
|
||||
(defn fetch-stock [params]
|
||||
{:customers (fetch-customers params)
|
||||
:products (get-all-products)})
|
||||
|
||||
(defn add-customer [{:keys [customer-name] :as params}]
|
||||
(swap! customers conj {:id (->> @customers (map :id) (apply max) inc)
|
||||
:name customer-name})
|
||||
(fetch-stock params))
|
||||
|
||||
(defn- day-customers [day] [day (->> day (get @days) (map (partial get @orders)))])
|
||||
(defn- days-between [from to]
|
||||
(time/days-range
|
||||
(int (/ (- (time/parse-date to) (time/parse-date from)) (* 24 3600000)))
|
||||
(time/parse-date from)))
|
||||
|
||||
|
||||
(defn fetch-days [{:keys [from to]}]
|
||||
(->> (days-between from to)
|
||||
(map time/iso-date)
|
||||
@ -61,24 +74,24 @@
|
||||
(println "replacing order" order)
|
||||
(let [order (update order :id #(or % (swap! id-counter inc)))]
|
||||
(swap! days (fn [ds] (update ds (:day order) #(distinct (conj % (:id order))))))
|
||||
(swap! customers #(assoc % (:id order) order))
|
||||
(swap! orders #(assoc % (:id order) order))
|
||||
{(->> order :day) (->> order :day day-customers second)}))
|
||||
|
||||
(defn- delete-order [{id :id}]
|
||||
(println "deleting order" id)
|
||||
(let [day (-> (get @customers id) :day)]
|
||||
(let [day (-> (get @orders id) :day)]
|
||||
(swap! days (fn [ds] (update ds day (partial remove #{id}))))
|
||||
(swap! customers #(dissoc % id))
|
||||
(swap! orders #(dissoc % id))
|
||||
{day (->> day day-customers second)}))
|
||||
|
||||
(defn- order-state [{id :id state :state :as bla}]
|
||||
(prn "fulfilling order" id state bla)
|
||||
(condp = state
|
||||
:fulfilled (->> id (get @customers) :products (swap! stock-products #(merge-with - %1 %2)))
|
||||
:waiting (->> id (get @customers) :products (swap! stock-products #(merge-with + %1 %2))))
|
||||
(let [day (-> (get @customers id) :day)]
|
||||
(swap! customers #(assoc-in % [id :state] state))
|
||||
(println id (get @customers id))
|
||||
: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] state))
|
||||
(println id (get @orders id))
|
||||
{day (->> day day-customers second)}))
|
||||
|
||||
|
||||
|
@ -1,6 +1,5 @@
|
||||
(ns chicken-master.calendar
|
||||
(:require
|
||||
[clojure.string :as str]
|
||||
[re-frame.core :as re-frame]
|
||||
[chicken-master.config :refer [settings]]
|
||||
[chicken-master.subs :as subs]
|
||||
@ -9,39 +8,24 @@
|
||||
[chicken-master.events :as event]
|
||||
[chicken-master.time :as time]))
|
||||
|
||||
(defn format-raw-order [{:strs [who notes] :as raw-values}]
|
||||
{:who who
|
||||
(defn format-raw-order [{:strs [who who-id notes] :as raw-values}]
|
||||
{:who {:name who :id (prod/num-or-nil who-id)}
|
||||
:notes notes
|
||||
:products (->> raw-values
|
||||
(remove (comp #{"who" "notes"} first))
|
||||
(remove (comp str/blank? second))
|
||||
(map (fn [[k v]] [(str/split k "-") v]))
|
||||
(group-by (comp last first))
|
||||
(map #(sort-by first (second %)))
|
||||
(map (fn [[[_ amount] [_ product]]] [(keyword product) (prod/num-or-nil amount)]))
|
||||
(remove (comp nil? first))
|
||||
(remove (comp zero? second))
|
||||
(group-by first)
|
||||
(map (fn [[product items]] [product (->> items (map last) (reduce +))]))
|
||||
(into {}))})
|
||||
:products (prod/collect-products (remove (comp #{"who" "notes"} first) raw-values))})
|
||||
|
||||
(defn edit-order []
|
||||
(html/modal
|
||||
:order-edit
|
||||
[:div
|
||||
(html/input :who "kto"
|
||||
{:required true
|
||||
:default @(re-frame/subscribe [::subs/order-edit-who])})
|
||||
(let [who @(re-frame/subscribe [::subs/order-edit-who])]
|
||||
[:div
|
||||
(html/input :who "kto" {:required true :default (:name who)})
|
||||
[:input {:id :who-id :name :who-id :type :hidden :value (or (:id who) "")}]])
|
||||
(html/input :notes "notka"
|
||||
{:default @(re-frame/subscribe [::subs/order-edit-notes])})
|
||||
(let [available-prods @(re-frame/subscribe [::subs/available-products])
|
||||
selected-prods @(re-frame/subscribe [::subs/order-edit-products])]
|
||||
[:div {:class :product-items-edit}
|
||||
(for [[i {product :prod amount :amount}] (map-indexed vector selected-prods)]
|
||||
(prod/product-item product amount available-prods i))])
|
||||
]
|
||||
[prod/products-edit @(re-frame/subscribe [::subs/order-edit-products])]]
|
||||
;; On success
|
||||
(fn [form] (prn (format-raw-order form))(re-frame/dispatch [::event/save-order (format-raw-order form)]))))
|
||||
(fn [form] (re-frame/dispatch [::event/save-order (format-raw-order form)]))))
|
||||
|
||||
(defn format-order [{:keys [id who day hour notes products state]}]
|
||||
[:div {:class [:order state] :key (gensym)}
|
||||
@ -56,7 +40,7 @@
|
||||
[::event/confirm-action
|
||||
"na pewno usunąć?"
|
||||
::event/remove-order id])} "-"]]
|
||||
[:div {:class :who} who]
|
||||
[:div {:class :who} (:name who)]
|
||||
(if (settings :show-order-time)
|
||||
[:div {:class :when} hour])
|
||||
(if (and (settings :show-order-notes) notes)
|
||||
@ -65,25 +49,28 @@
|
||||
(map prod/format-product)
|
||||
(into [:div {:class :products}]))])
|
||||
|
||||
(defn day [{:keys [date customers]}]
|
||||
(defn day [{:keys [date orders]}]
|
||||
[:div {:class [:day (when (time/today? date) :today)]}
|
||||
[:div {:class :day-header} (time/format-date date)]
|
||||
[:div
|
||||
[:div {:class :orders}
|
||||
(if (settings :hide-fulfilled-orders)
|
||||
(->> customers (remove (comp #{:fulfilled} :state)) (map format-order))
|
||||
(map format-order customers))
|
||||
[:button {:type :button
|
||||
:on-click #(re-frame/dispatch [::event/edit-order (time/iso-date date)])} "+"]
|
||||
(when (seq (map :products customers))
|
||||
(->> orders (remove (comp #{:fulfilled} :state)) (map format-order))
|
||||
(map format-order orders))
|
||||
(when (settings :show-day-add-order)
|
||||
[:button {:type :button
|
||||
:on-click #(re-frame/dispatch [::event/edit-order (time/iso-date date)])} "+"])
|
||||
(when (seq (map :products orders))
|
||||
[:div {:class :summary}
|
||||
[:hr {:class :day-seperator}]
|
||||
[:div {:class :header} "w sumie:"]
|
||||
(->> customers
|
||||
(->> orders
|
||||
(map :products)
|
||||
(apply merge-with +)
|
||||
(sort-by first)
|
||||
(map prod/format-product)
|
||||
(into [:div {:class :products-sum}]))])]]])
|
||||
(into [:div {:class :products-sum}]))])
|
||||
]]])
|
||||
|
||||
(defn calendar-header []
|
||||
(->> (:day-names settings)
|
||||
|
@ -8,6 +8,7 @@
|
||||
:calendar-heading false ; show a header with the names of days
|
||||
:show-date true ; display the date for each day
|
||||
:show-day-name-with-date true ; add the day name to each date
|
||||
:show-day-add-order false ; Show an add order button in each day
|
||||
|
||||
:show-order-time false ; display the time of each order
|
||||
:show-order-notes true ; display notes
|
||||
|
@ -20,6 +20,5 @@
|
||||
|
||||
(defn init []
|
||||
(re-frame/dispatch-sync [::events/initialize-db])
|
||||
(re-frame/dispatch-sync [::events/show-from-date (new js/Date)])
|
||||
(dev-setup)
|
||||
(mount-root))
|
||||
|
56
src/cljs/chicken_master/customers.cljs
Normal file
56
src/cljs/chicken_master/customers.cljs
Normal file
@ -0,0 +1,56 @@
|
||||
(ns chicken-master.customers
|
||||
(:require
|
||||
[re-frame.core :as re-frame]
|
||||
[reagent.core :as reagent]
|
||||
[chicken-master.config :refer [settings]]
|
||||
[chicken-master.products :as prod]
|
||||
[chicken-master.subs :as subs]
|
||||
[chicken-master.html :as html]
|
||||
[chicken-master.events :as event]))
|
||||
|
||||
(defn item-adder [& {:keys [type value callback button class]
|
||||
:or {type :text value "" button nil}}]
|
||||
(let [state (reagent/atom value)]
|
||||
(fn []
|
||||
[:div {:class class :on-click #(.stopPropagation %)}
|
||||
[:input {:type type :name :user-name :default value :value @state
|
||||
:on-change #(let [val (-> % .-target .-value)]
|
||||
(reset! state val)
|
||||
(if-not button (callback val)))}]
|
||||
(if button
|
||||
[:button {:class :add-product
|
||||
:type :button
|
||||
:disabled (= @state "")
|
||||
:on-click (if callback #(-> state (reset-vals! value) first callback))} button])])))
|
||||
|
||||
(defn order-adder [order]
|
||||
(let [state (reagent/atom order)]
|
||||
(fn []
|
||||
[:details {:class :customer-order :key (gensym) :open (:open @state)}
|
||||
[:summary {:on-click #(swap! state update :open not)}
|
||||
[item-adder
|
||||
:type :date
|
||||
:value (:day @state)
|
||||
:class :order-date-picker
|
||||
:callback (fn [day] (swap! state #(assoc % :day day :open true)))]]
|
||||
(if (:day @state)
|
||||
[prod/products-edit (:products @state)
|
||||
:getter-fn #(re-frame/dispatch [::event/save-order (assoc @state :products %)])])])))
|
||||
|
||||
(defn show-customers []
|
||||
(html/modal
|
||||
:clients
|
||||
[:div {:class :customers-modal}
|
||||
[:h2 "Clienci"]
|
||||
[item-adder :callback #(re-frame/dispatch [::event/add-customer %]) :button "+"]
|
||||
(let [client-orders (->> @(re-frame/subscribe [::subs/orders])
|
||||
vals
|
||||
(group-by #(get-in % [:who :id])))]
|
||||
(for [{:keys [name id] :as who} @(re-frame/subscribe [::subs/available-customers])]
|
||||
[:details {:class "client" :key (gensym)}
|
||||
[:summary name]
|
||||
(for [order (sort-by :day (client-orders id))]
|
||||
[order-adder (assoc order :key (gensym))])
|
||||
[order-adder who :class :new-user]
|
||||
]))]
|
||||
))
|
@ -2,9 +2,6 @@
|
||||
|
||||
(def default-db
|
||||
{;; set automatically
|
||||
;; :customers {1 {:id 1 :who "mr.blobby (649 234 234)" :day "2020-10-10" :hour "02:12" :products {:eggs 2 :milk 3}}
|
||||
;; 2 {:id 2 :who "da police (0118 999 881 999 119 725 123123 12 3123 123 )" :day "2020-10-10" :hour "02:12" :products {:eggs 12}}
|
||||
;; 3 {:id 3 :who "johnny" :day "2020-10-10" :hour "02:12" :products {:eggs 5}}}
|
||||
;; :days {"2020-10-05" [1 2 3]
|
||||
;; "2020-10-06" [1 2 3]
|
||||
;; "2020-10-07" [1 2 3]
|
||||
@ -24,6 +21,11 @@
|
||||
;; :show-confirmation-modal {:show nil
|
||||
;; :on-confirm-event :bla-bla-bla
|
||||
;; :params [1 2 3]}
|
||||
|
||||
|
||||
;; :current-days [{:day (google.date "2020-01-01") :orders []}]
|
||||
;; :customers []
|
||||
::clients {:show nil} ; customers edit modal
|
||||
:stock {:show nil}
|
||||
:products {:eggs 22 :milk 32 :cabbage 54 :carrots 11 :cows 32 :ants 21}
|
||||
})
|
||||
|
@ -7,7 +7,16 @@
|
||||
;; 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-fx
|
||||
::initialize-db
|
||||
(fn [_ _]
|
||||
{:db db/default-db
|
||||
:dispatch [::show-from-date (new js/Date)]
|
||||
:http {:method :post
|
||||
:url "get-stock"
|
||||
: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)))
|
||||
|
||||
@ -28,19 +37,17 @@
|
||||
|
||||
(re-frame/reg-event-db
|
||||
::edit-order
|
||||
(fn [{customers :customers :as db} [_ day id]]
|
||||
(fn [{orders :orders :as db} [_ day id]]
|
||||
(assoc db :order-edit
|
||||
(-> customers
|
||||
(-> orders
|
||||
(get id {:state :waiting})
|
||||
(update :products (comp vec (partial map (partial zipmap [:prod :amount]))))
|
||||
(update :products conj {})
|
||||
(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]]]
|
||||
{:db (assoc-in db [:orders id :state] :pending)
|
||||
:dispatch [::set-current-days]
|
||||
:http {:method :post
|
||||
:url "fulfill-order"
|
||||
:params {:id id}
|
||||
@ -50,7 +57,7 @@
|
||||
(re-frame/reg-event-fx
|
||||
::reset-order
|
||||
(fn [{db :db} [_ id]]
|
||||
{:db (assoc-in db [:customers id :state] :waiting)
|
||||
{:db (assoc-in db [:orders id :state] :waiting)
|
||||
:fx [[:dispatch [::set-current-days]]]
|
||||
:http {:method :post
|
||||
:url "reset-order"
|
||||
@ -61,12 +68,12 @@
|
||||
(re-frame/reg-event-fx
|
||||
::save-order
|
||||
(fn [{{order :order-edit} :db} [_ form]]
|
||||
{:fx [[:dispatch [::hide-modal :order-edit]]]
|
||||
{: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]))
|
||||
(select-keys form [:id :day :hour :state :who :notes :products]))
|
||||
:on-success [::process-fetched-days]
|
||||
:on-fail [::failed-blah]}}))
|
||||
|
||||
@ -83,12 +90,12 @@
|
||||
(assoc-in db [:order-edit :products product-no :amount] amount)))
|
||||
|
||||
|
||||
(defn get-day [{:keys [days customers]} date]
|
||||
(defn get-day [{:keys [days orders]} date]
|
||||
{:date date
|
||||
:customers (->> date
|
||||
time/iso-date
|
||||
(get days)
|
||||
(map customers))})
|
||||
:orders (->> date
|
||||
time/iso-date
|
||||
(get days)
|
||||
(map orders))})
|
||||
|
||||
(re-frame/reg-event-db
|
||||
::set-current-days
|
||||
@ -106,7 +113,7 @@
|
||||
(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))))
|
||||
(update :orders #(reduce (fn [m cust] (assoc m (:id cust) cust)) % (-> days vals flatten))))
|
||||
:fx [[:dispatch [::set-current-days]]
|
||||
[:dispatch [::fetch-stock]]]}))
|
||||
|
||||
@ -126,14 +133,14 @@
|
||||
(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)))]]]}))
|
||||
{: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]]]}]
|
||||
:dispatch [::set-current-days]}]
|
||||
(if-not missing
|
||||
effects
|
||||
(assoc effects :http {:method :get
|
||||
@ -141,6 +148,21 @@
|
||||
:params missing
|
||||
:on-success [::process-fetched-days]
|
||||
:on-fail [::failed-blah]})))))
|
||||
;; Customers events
|
||||
(re-frame/reg-event-fx
|
||||
::show-customers
|
||||
(fn [{db :db} _]
|
||||
{:db (assoc-in db [:clients :show] true)
|
||||
:dispatch [::fetch-stock]}))
|
||||
|
||||
(re-frame/reg-event-fx
|
||||
::add-customer
|
||||
(fn [_ [_ customer-name]]
|
||||
{:http {:method :post
|
||||
:url "add-customer"
|
||||
:params {:customer-name customer-name}
|
||||
:on-success [::process-stock]
|
||||
:on-fail [::failed-blah]}}))
|
||||
|
||||
;;; Storage events
|
||||
|
||||
@ -148,21 +170,23 @@
|
||||
::show-stock
|
||||
(fn [{db :db} _]
|
||||
{:db (assoc-in db [:stock :show] true)
|
||||
:fx [[:dispatch [::fetch-stock]]]}))
|
||||
:dispatch [::fetch-stock]}))
|
||||
|
||||
(re-frame/reg-event-fx
|
||||
::fetch-stock
|
||||
(fn [_ _]
|
||||
{:http {:method :get
|
||||
:url "get-all-products"
|
||||
:url "get-stock"
|
||||
: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)))
|
||||
(fn [db [_ {:keys [products customers]}]]
|
||||
(println "fetched stock" products)
|
||||
(assoc db
|
||||
:products products
|
||||
:customers customers)))
|
||||
|
||||
(re-frame/reg-event-db
|
||||
::update-product-stock
|
||||
@ -184,7 +208,7 @@
|
||||
(re-frame/reg-event-fx
|
||||
::save-stock
|
||||
(fn [{db :db} [_ products]]
|
||||
{:fx [[:dispatch [::hide-modal :stock]]]
|
||||
{:dispatch [::hide-modal :stock]
|
||||
:http {:method :post
|
||||
:url "save-stock"
|
||||
:body products
|
||||
@ -212,6 +236,9 @@
|
||||
"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)))
|
||||
"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)))
|
||||
)))
|
||||
|
@ -25,24 +25,32 @@
|
||||
([id label] (input id label {}))
|
||||
([id label options]
|
||||
[:div {:class :input-item}
|
||||
[:label {:for id} label]
|
||||
(if label [:label {:for id} label])
|
||||
[:input (-> options
|
||||
(assoc :defaultValue (:default options))
|
||||
(dissoc :default)
|
||||
(merge {:name id :id id}))]]))
|
||||
|
||||
|
||||
(defn modal [modal-id content on-submit]
|
||||
[:div {:class :popup}
|
||||
[:form {:action "#"
|
||||
:on-submit (fn [e]
|
||||
(.preventDefault e)
|
||||
(when (-> e .-target form-values on-submit)
|
||||
(re-frame/dispatch [::event/hide-modal])))}
|
||||
content
|
||||
[:div {:class :form-buttons}
|
||||
[:button "ok"]
|
||||
[:button {:type :button :on-click #(re-frame/dispatch [::event/hide-modal modal-id])} "anuluj"]]]])
|
||||
(defn modal
|
||||
([modal-id content]
|
||||
[:div {:class :popup}
|
||||
[:div {:class :popup-content}
|
||||
content
|
||||
[:div {:class :form-buttons}
|
||||
[:button {:type :button :on-click #(re-frame/dispatch [::event/hide-modal modal-id])} "ok"]]]])
|
||||
([modal-id content on-submit]
|
||||
[:div {:class :popup}
|
||||
[:form {:action "#"
|
||||
:class :popup-content
|
||||
:on-submit (fn [e]
|
||||
(.preventDefault e)
|
||||
(when (-> e .-target form-values on-submit)
|
||||
(re-frame/dispatch [::event/hide-modal modal-id])))}
|
||||
content
|
||||
[:div {:class :form-buttons}
|
||||
[:button "ok"]
|
||||
[:button {:type :button :on-click #(re-frame/dispatch [::event/hide-modal modal-id])} "anuluj"]]]]))
|
||||
|
||||
|
||||
(comment
|
||||
|
@ -1,8 +1,11 @@
|
||||
(ns chicken-master.products
|
||||
(:require
|
||||
[clojure.string :as str]
|
||||
[re-frame.core :as re-frame]
|
||||
[reagent.core :as reagent]
|
||||
[chicken-master.config :refer [settings]]
|
||||
[chicken-master.html :as html]
|
||||
[chicken-master.subs :as subs]
|
||||
[chicken-master.events :as event]))
|
||||
|
||||
(defn num-or-nil [val]
|
||||
@ -20,21 +23,55 @@
|
||||
:step :any
|
||||
:on-blur on-blur}))
|
||||
|
||||
(defn product-item [what amount available product-no]
|
||||
(defn collect-products [raw-values]
|
||||
(->> raw-values
|
||||
(remove (comp str/blank? second))
|
||||
(map (fn [[k v]] [(str/split k "-") v]))
|
||||
(group-by (comp last first))
|
||||
(map #(sort-by first (second %)))
|
||||
(map (fn [[[_ amount] [_ product]]] [(keyword product) (num-or-nil amount)]))
|
||||
(remove (comp nil? first))
|
||||
(remove (comp zero? second))
|
||||
(group-by first)
|
||||
(map (fn [[product items]] [product (->> items (map last) (reduce +))]))
|
||||
(into {})))
|
||||
|
||||
(defn product-item [available state what]
|
||||
(let [id (gensym)]
|
||||
[:div {:class :product-item-edit :key (gensym)}
|
||||
[:div {:class :input-item}
|
||||
[:label {:for :product} "co"]
|
||||
;; [:label {:for :product} "co"]
|
||||
[:select {:name (str "product-" id) :id :product :defaultValue what
|
||||
:on-change #(re-frame/dispatch [::event/selected-product (-> % .-target .-value) product-no])}
|
||||
:on-change #(let [prod (-> % .-target .-value keyword)]
|
||||
(swap! state assoc prod (+ (@state prod) (@state what)))
|
||||
(swap! state dissoc what)
|
||||
(if (not (contains? @state nil))
|
||||
(swap! state assoc nil 0))
|
||||
)}
|
||||
[:option {:value ""} "-"]
|
||||
(for [[product _] available]
|
||||
[:option {:key (gensym) :value product} (name product)])]
|
||||
]
|
||||
(number-input (str "amount-" id) "ile" amount
|
||||
#(re-frame/dispatch [::event/changed-amount (-> % .-target .-value) product-no]))
|
||||
(number-input (str "amount-" id) nil (@state what)
|
||||
#(do (swap! state assoc what (-> % .-target .-value num-or-nil))
|
||||
(prn @state)))
|
||||
]))
|
||||
|
||||
(defn products-edit [selected-prods & {:keys [available-prods getter-fn]
|
||||
:or {available-prods @(re-frame/subscribe [::subs/available-products])}}]
|
||||
(let [state (reagent/atom (assoc selected-prods nil 0))]
|
||||
(fn []
|
||||
(let [products (->> @state
|
||||
keys
|
||||
(map (partial product-item available-prods state))
|
||||
(into [:div {:class :product-items-edit}]))]
|
||||
(if getter-fn
|
||||
(conj products
|
||||
[:button {:type :button
|
||||
:on-click #(getter-fn (dissoc @state nil))} "ok"])
|
||||
products
|
||||
)))))
|
||||
|
||||
(defn format-product [[product amount]]
|
||||
[:div {:key (gensym) :class :product}
|
||||
[:span {:class :product-name} product]
|
||||
|
@ -3,9 +3,12 @@
|
||||
|
||||
(re-frame/reg-sub ::name (fn [db] (:name db)))
|
||||
(re-frame/reg-sub ::available-products (fn [db] (:products db)))
|
||||
(re-frame/reg-sub ::available-customers (fn [db] (:customers db)))
|
||||
(re-frame/reg-sub ::orders (fn [db] (:orders db)))
|
||||
|
||||
(re-frame/reg-sub ::show-edit-modal (fn [db] (-> db :order-edit :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 ::order-edit-who (fn [db] (println (:order-edit db)) (-> db :order-edit :who)))
|
||||
(re-frame/reg-sub ::order-edit-notes (fn [db] (-> db :order-edit :notes)))
|
||||
|
@ -3,24 +3,27 @@
|
||||
[re-frame.core :as re-frame]
|
||||
[chicken-master.subs :as subs]
|
||||
[chicken-master.stock :as stock]
|
||||
[chicken-master.customers :as cust]
|
||||
[chicken-master.calendar :as cal]
|
||||
[chicken-master.events :as event]))
|
||||
|
||||
|
||||
(defn main-panel []
|
||||
(let [name (re-frame/subscribe [::subs/name])]
|
||||
[:div {:class :full-height}
|
||||
(cond
|
||||
@(re-frame/subscribe [::subs/show-stock-modal]) (stock/show-available)
|
||||
@(re-frame/subscribe [::subs/show-edit-modal]) (cal/edit-order))
|
||||
[:div {:class :full-height}
|
||||
(cond
|
||||
@(re-frame/subscribe [::subs/show-stock-modal]) (stock/show-available)
|
||||
@(re-frame/subscribe [::subs/show-customers-modal]) (cust/show-customers)
|
||||
@(re-frame/subscribe [::subs/show-edit-modal]) (cal/edit-order))
|
||||
|
||||
[:button {:id :show-stock-button :class :menu-button :on-click #(re-frame/dispatch [::event/show-stock])} "Magazyn"]
|
||||
[:button {:id :scroll-up-button :class [:menu-button :scroll-button] :on-click #(re-frame/dispatch [::event/scroll-weeks -2])} "^"]
|
||||
[:button {:id :show-stock-button :class :menu-button :on-click #(re-frame/dispatch [::event/show-stock])} "Magazyn"]
|
||||
[:button {:id :show-clients-button :class :menu-button :on-click #(re-frame/dispatch [::event/show-customers])} "Klienci"]
|
||||
|
||||
[:div {:class :scroll-bar}
|
||||
[:button {:id :scroll-up :on-click #(re-frame/dispatch [::event/scroll-weeks -2])} "^"]
|
||||
[:button {:id :scroll-down :on-click #(re-frame/dispatch [::event/scroll-weeks 2])} "v"]]
|
||||
[:button {:id :scroll-up-button :class [:menu-button :scroll-button] :on-click #(re-frame/dispatch [::event/scroll-weeks -2])} "^"]
|
||||
|
||||
(cal/calendar @(re-frame/subscribe [::subs/current-days]))
|
||||
[:button {:id :scroll-down-button :class [:menu-button :scroll-button] :on-click #(re-frame/dispatch [::event/scroll-weeks 2])} "v"]
|
||||
]))
|
||||
[:div {:class :scroll-bar}
|
||||
[:button {:id :scroll-up :on-click #(re-frame/dispatch [::event/scroll-weeks -2])} "^"]
|
||||
[:button {:id :scroll-down :on-click #(re-frame/dispatch [::event/scroll-weeks 2])} "v"]]
|
||||
|
||||
(cal/calendar @(re-frame/subscribe [::subs/current-days]))
|
||||
[:button {:id :scroll-down-button :class [:menu-button :scroll-button] :on-click #(re-frame/dispatch [::event/scroll-weeks 2])} "v"]
|
||||
])
|
||||
|
@ -1,43 +1,45 @@
|
||||
(ns chicken-master.calendar-test
|
||||
(ns chicken-master.sutendar-test
|
||||
(:require
|
||||
[chicken-master.calendar :as cal]
|
||||
[chicken-master.calendar :as sut]
|
||||
[cljs.test :refer-macros [deftest is testing]]))
|
||||
|
||||
(deftest format-raw-order-test
|
||||
(testing "no products"
|
||||
(is (= (cal/format-raw-order {}) {:who nil :notes nil :products {}}))
|
||||
(is (= (cal/format-raw-order {"who" "bla" "notes" "ble"})
|
||||
{:who "bla" :notes "ble" :products {}})))
|
||||
(is (= (sut/format-raw-order {}) {:who {:name nil :id nil} :notes nil :products {}}))
|
||||
(is (= (sut/format-raw-order {"who" "bla" "notes" "ble"})
|
||||
{:who {:name "bla" :id nil} :notes "ble" :products {}}))
|
||||
(is (= (sut/format-raw-order {"who" "bla" "who-id" "123" "notes" "ble"})
|
||||
{:who {:name "bla" :id 123} :notes "ble" :products {}})))
|
||||
|
||||
(testing "decent products"
|
||||
(is (= (cal/format-raw-order {"who" "bla" "notes" "ble"
|
||||
(is (= (sut/format-raw-order {"who" "bla" "who-id" "123" "notes" "ble"
|
||||
"product-eggs" "eggs" "amount-eggs" "12"
|
||||
"product-cows" "cows" "amount-cows" "22"
|
||||
"product-milk" "milk" "amount-milk" "3.2"})
|
||||
{:who "bla" :notes "ble" :products {:eggs 12 :cows 22 :milk 3.2}})))
|
||||
{:who {:name "bla" :id 123} :notes "ble" :products {:eggs 12 :cows 22 :milk 3.2}})))
|
||||
|
||||
(testing "duplicate products"
|
||||
(is (= (cal/format-raw-order {"who" "bla" "notes" "ble"
|
||||
(is (= (sut/format-raw-order {"who" "bla" "who-id" "123" "notes" "ble"
|
||||
"product-eggs" "eggs" "amount-eggs" "12"
|
||||
"product-eggs1" "eggs" "amount-eggs1" "12"
|
||||
"product-cows1" "cows" "amount-cows1" "1"
|
||||
"product-cows2" "cows" "amount-cows2" "2"
|
||||
"product-milk" "milk" "amount-milk" "3.2"})
|
||||
{:who "bla" :notes "ble" :products {:eggs 24 :cows 3 :milk 3.2}})))
|
||||
{:who {:name "bla" :id 123} :notes "ble" :products {:eggs 24 :cows 3 :milk 3.2}})))
|
||||
|
||||
(testing "unselected are ignored"
|
||||
(is (= (cal/format-raw-order {"who" "bla" "notes" "ble"
|
||||
(is (= (sut/format-raw-order {"who" "bla" "who-id" "123" "notes" "ble"
|
||||
"product-eggs" "eggs" "amount-eggs" "12"
|
||||
"product-bad1" "" "amount-bad1" "12"
|
||||
"product-bad2" "" "amount-bad2" "1"
|
||||
"product-milk" "milk" "amount-milk" "3.2"
|
||||
"product-bad3" "" "amount-bad3" "2"})
|
||||
{:who "bla" :notes "ble" :products {:eggs 12 :milk 3.2}})))
|
||||
{:who {:name "bla" :id 123} :notes "ble" :products {:eggs 12 :milk 3.2}})))
|
||||
|
||||
(testing "items with 0 are removed"
|
||||
(is (= (cal/format-raw-order {"who" "bla" "notes" "ble"
|
||||
(is (= (sut/format-raw-order {"who" "bla" "who-id" "123" "notes" "ble"
|
||||
"product-eggs" "eggs" "amount-eggs" "12"
|
||||
"product-eggs1" "eggs" "amount-eggs1" "0"
|
||||
"product-cow" "cow" "amount-cow" "0"
|
||||
"product-milk" "milk" "amount-milk" "3.2"})
|
||||
{:who "bla" :notes "ble" :products {:eggs 12 :milk 3.2}}))))
|
||||
{:who {:name "bla" :id 123} :notes "ble" :products {:eggs 12 :milk 3.2}}))))
|
||||
|
Loading…
x
Reference in New Issue
Block a user