Explorar o código

extracted order to its own module that emits objects that build an order request

Harlan Iverson %!s(int64=5) %!d(string=hai) anos
pai
achega
e641e9f916
Modificáronse 2 ficheiros con 126 adicións e 40 borrados
  1. 39 40
      src/pos_demo/core.cljs
  2. 87 0
      src/pos_demo/order.cljs

+ 39 - 40
src/pos_demo/core.cljs

@@ -5,7 +5,12 @@
               [cljs-http.client :as http]
               [cljs.core.async :as async]
               [decimal.core :as decimal]
-              [pos-demo.menu :as menu]))
+              [pos-demo.menu :as menu]
+              [pos-demo.order :as order]))
+
+(cljs.reader/register-tag-parser! 'pos-demo.order.Order order/map->Order)
+(cljs.reader/register-tag-parser! 'pos-demo.order.OrderItem order/map->OrderItem)
+(cljs.reader/register-tag-parser! 'pos-demo.order.OrderItemIngredient order/map->OrderItemIngredient)
 
 (enable-console-print!)
 
@@ -20,31 +25,6 @@
 
 ; rules translate requests into items. Some requests will have no effect on the order.
 
-(defrecord OrderItemIngredientModification
-  [ingredient operation])
-
-(defrecord OrderItemOption
-  [])
-
-(defrecord OrderItem
-  [order menu-item ingredient-mods options])
-
-(defrecord Order
-  [id])  
-
-
-(defrecord OrderRequest
-  [order description])
-  
-  
-
-(defn order-total [order]
-  (let [item-prices (map :price (:items order))
-        total-price (reduce decimal/+
-                            "0.00"
-                            item-prices)]
-    total-price))
-
 ;(defrule add-any-requested-item
 ;  [OrderRequest order-request ()]
 ;  =>
@@ -61,24 +41,29 @@
 
 (defn new-order
   []
-  (swap! app-state assoc :active-order {:id (str (current-date)) :items []}))
+  (swap! app-state assoc :active-order 1))
 
 (defn abandon-order
   []
   (swap! app-state assoc :active-order nil)
-  (swap! app-state assoc :payment-amount "0.00"))
+  (swap! app-state assoc :payment-amount "0.00")
+  (reset! order/order-store []))
+
 
 (defn save-order
   []
-  (js/prompt "Save the text; it can be loaded, later." (pr-str (:active-order @app-state))))
+  (js/prompt "Save the text; it can be loaded, later." (pr-str @pos-demo.order/order-store)))
+
+
 
 (defn load-order
   []
   (let [order-edn (js/prompt "Paste the saved text.")]
-    (when-let [order (read-string order-edn)]
-      (when (map? order)
-        (swap! app-state assoc :active-order order)
-        (swap! app-state assoc :payment-amount (str (order-total order)))))
+    (when-let [order-store (read-string order-edn)]
+      (when order-store
+        (reset! order/order-store order-store)
+        (swap! app-state assoc :active-order 1)
+        (swap! app-state assoc :payment-amount (str (order/order-total 1	)))))
     ))
 
 (defn ping-api
@@ -166,9 +151,15 @@
   )
 
 (defn add-menu-item-to-order
-  [menu-item]
-  (swap! app-state update-in [:active-order :items] conj (select-keys menu-item [:title :price]))
-  (swap! app-state assoc :payment-amount (str (order-total (:active-order @app-state))))
+  [menu-item-id]
+  ;(swap! app-state update-in [:active-order :items] conj (select-keys menu-item [:title :price]))
+  (let [ingredient-mods (if (= 102 menu-item-id) 
+                            {"Bread" {:operation :skip}
+                             "Lettuce" {:operation :add}}
+                             {})
+        request (order/request-menu-item (:active-order @app-state) menu-item-id ingredient-mods)]
+    (order/add-item request))
+  (swap! app-state assoc :payment-amount (str (order/order-total (:active-order @app-state))))
   )
 
 (defn menu-item-clicked
@@ -181,7 +172,7 @@
 (defn add-item-clicked
   [menu item]
   (swap! app-state dissoc :customize-menu-item)
-  (add-menu-item-to-order item)
+  (add-menu-item-to-order (:id item))
   (.scrollTo js/window 0 0)
   )
 
@@ -216,13 +207,21 @@
   
   [:div 
   [:ul 
-    (for [item (:items order)]
-      [:li (:title item) [:span.price (:price item)]]
+    (for [item (order/order-items order)]
+      [:li (:title item) [:span.price (:price item)]
+        [:ul
+          (let [item-ingredients (order/item-ingredients (:id item))
+                item-ingredients (filter #(not= :normal (:operation %)) item-ingredients)
+                                     
+                                     ]
+          (for [ingredient item-ingredients]
+            [:li (:operation ingredient) (:ingredient ingredient)]))]      
+      ]
       )]
   
     [:div
       [:strong "Total Price"]
-      [:span (str (order-total order))]]])
+      [:span (str (order/order-total order))]]])
 
 (defn customize-menu-item [menu-item]
   [:div#product-customization-dialog

+ 87 - 0
src/pos_demo/order.cljs

@@ -0,0 +1,87 @@
+(ns pos-demo.order
+  (:require [pos-demo.menu :as menu]
+            [decimal.core :as decimal]))
+
+
+
+; Scenario -- one taco left, two guests on two terminals want it. who gets it?
+
+(defrecord Order
+  [id])  
+
+(defrecord OrderItem
+  [id order menu-item title price])
+
+
+(defrecord OrderItemIngredient
+  [id order-item ingredient operation quantity price])
+
+(defrecord OrderRequest
+  [order description])
+
+
+(def order-store (atom [(map->Order {:id 1})]))
+
+
+; The order is made up of a collection of facts.
+; They are all committed in the same Transaction.
+; They have relative temporary IDs that are updated upon commit.
+; We could omit OrderItemIngredients and refer back to the menu data at a point in time.
+;  We should do this in view rendering, if we don't explicitly include it. Assume menu won't change between order and cooking.
+
+
+(def next-id (atom 1))
+
+(defn request-menu-item
+  [order-id menu-item-id ingredient-mods] ; mods are a map of ingredient {:operation}
+  (let [menu-item (menu/find-menu-item menu-item-id)
+        order-item (map->OrderItem {:id (swap! next-id inc)
+                                    :order order-id
+                                    :price (:price menu-item)
+                                    :title (:title menu-item)
+                                    :menu-item (:id menu-item)})
+        
+        normal-ingredients (->> (menu/find-menu-item-ingredients menu-item-id)
+         (filter #(not (and (contains? ingredient-mods (:ingredient %))
+                                              (not= (:operation %) :normal))))
+         (map #(map->OrderItemIngredient {:order-item (:id order-item)
+                                                            :ingredient (:ingredient %)
+                                                            :operation :normal}))
+                         )
+                         
+        modified-ingredients (map #(map->OrderItemIngredient {:order-item (:id order-item)
+                                                              :ingredient (key %)
+                                                              :operation (:operation (val %))})
+                         ingredient-mods)       
+        
+        ]
+    (concat [order-item] normal-ingredients modified-ingredients)
+    ))
+
+
+(defn add-item
+  [requests]
+  (swap! order-store concat requests)
+  )
+
+(defn order-items
+  [order-id]
+  (filter #(and (instance? OrderItem %)
+                (= (:order %) order-id))
+          @order-store)) 
+          
+          
+(defn item-ingredients
+  [order-item-id]
+  (filter #(and (instance? OrderItemIngredient %)
+                (= (:order-item %) order-item-id))
+          @order-store))
+   
+
+(defn order-total [order-id]
+  (let [item-prices (map :price (order-items order-id))
+        total-price (reduce decimal/+
+                            "0.00"
+                            item-prices)]
+    total-price))
+