From b4ed659718ee32cc0c164b0ae99360e66354add3 Mon Sep 17 00:00:00 2001 From: Daniel O'Connell Date: Wed, 20 Apr 2022 13:03:52 +0200 Subject: [PATCH] fix updating non recurring items --- .../migrations/005-move-statuses.edn | 2 +- backend/src/chicken_master/api.clj | 7 +- backend/src/chicken_master/orders.clj | 137 +++++++++++----- backend/src/chicken_master/time.clj | 22 ++- backend/test/chicken_master/orders_test.clj | 148 ++++++++++++------ frontend/src/chicken_master/calendar.cljs | 11 +- frontend/src/chicken_master/events.cljs | 15 +- 7 files changed, 230 insertions(+), 112 deletions(-) diff --git a/backend/resources/migrations/005-move-statuses.edn b/backend/resources/migrations/005-move-statuses.edn index 670bee9..ad81f85 100644 --- a/backend/resources/migrations/005-move-statuses.edn +++ b/backend/resources/migrations/005-move-statuses.edn @@ -1,6 +1,6 @@ {:up ["INSERT INTO recurrence_exceptions (order_id, order_date, status) SELECT id AS order_id, order_date, status FROM orders - WHERE status != 'waiting' + WHERE status = 'fulfilled' ON conflict do nothing" "ALTER TABLE orders DROP COLUMN status"] :down ["ALTER TABLE orders ADD status order_state DEFAULT 'waiting'" diff --git a/backend/src/chicken_master/api.clj b/backend/src/chicken_master/api.clj index 6bf60c5..00b582f 100644 --- a/backend/src/chicken_master/api.clj +++ b/backend/src/chicken_master/api.clj @@ -43,7 +43,8 @@ order (-> request :body (update :id #(or % id)))] (as-edn (orders/replace! user-id order)))) -(defn delete-order [user-id id day] (->> id edn/read-string (orders/delete! user-id day) as-edn)) +(defn delete-order [user-id id action-type day] + (->> id edn/read-string (orders/delete! user-id action-type day) as-edn)) (defn set-order-state [user-id id day status] (as-edn (orders/change-state! user-id (edn/read-string id) day status))) (defn get-stock [user-id] (get-values user-id [:customers :products])) @@ -64,5 +65,7 @@ (GET "/orders" [:as {user-id :basic-authentication}] (get-orders user-id)) (POST "/orders" request (update-order request)) (PUT "/orders/:id" request (update-order request)) - (DELETE "/orders/:id" [id :as {user-id :basic-authentication body :body}] (delete-order user-id id (:day body))) + (DELETE "/orders/:id" [id :as {user-id :basic-authentication}] (delete-order user-id id nil nil)) + (POST "/orders/:id/remove" [id :as {user-id :basic-authentication body :body}] + (delete-order user-id id (:day body) (:action-type body))) (POST "/orders/:id/:status" [id status :as {user-id :basic-authentication body :body}] (set-order-state user-id id (:day body) status))) diff --git a/backend/src/chicken_master/orders.clj b/backend/src/chicken_master/orders.clj index 342ad56..8ca0efc 100644 --- a/backend/src/chicken_master/orders.clj +++ b/backend/src/chicken_master/orders.clj @@ -7,14 +7,83 @@ [chicken-master.customers :as customers] [chicken-master.time :as t])) -(defn upsert-order! [tx user-id customer-id {:keys [id day notes]}] - (let [order {:customer_id customer-id - :notes notes - :order_date (some-> day t/to-db-date) - :end_date (some-> day t/to-db-date)}] - (if (db/get-by-id tx user-id :orders id) - (do (sql/update! tx :orders order {:id id}) id) - (:orders/id (sql/insert! tx :orders (assoc order :user_id user-id)))))) +(defn assoc? [coll & key-vals] + (->> key-vals + (partition 2) + (filter second) + (reduce (fn [c [k v]] (assoc c k v)) coll))) + +(defn recurrence-exception? [tx order-id day] + (jdbc/execute-one! tx + ["SELECT * from recurrence_exceptions WHERE order_id = ? AND order_date = ?" + order-id (t/to-db-date day)])) + +(defn upsert-exception! [tx order-id day state] + (let [item {:order_id order-id :order_date (t/to-db-date day)}] + (if (= state "waiting") + (sql/delete! tx :recurrence_exceptions item) + + (if (recurrence-exception? tx order-id day) + (sql/update! tx :recurrence_exceptions {:status (jdbc.types/as-other state)} item) + (sql/insert! tx :recurrence_exceptions (assoc item :status (jdbc.types/as-other state))))))) + +(defn set-dates [order updates] + (let [recurrence (or (:recurrence updates) (:orders/recurrence order)) + day (or (:order_date updates) (:orders/order_date order)) + end-date (if recurrence (t/last-date day recurrence) day)] + (assoc updates + :recurrence recurrence + :order_date (t/to-db-date day) + :end_date (t/to-db-date end-date)))) + +(defn duplicate-order! [tx user-id order updates] + (->> updates + (merge {:user_id user-id}) + (set-dates order) + (sql/insert! tx :orders) + :orders/id)) + +(defn update-non-recurring [tx order updates] + (let [order-id (:orders/id order) + current-date (:orders/order_date order) + {:keys [order_date] :as dates} (set-dates order updates)] + (sql/update! tx :orders dates {:id order-id}) + + ;; Make sure any status changes get copied over + (when-let [exception (recurrence-exception? tx order-id current-date)] + (upsert-exception! tx order-id current-date "waiting") ; make use of the fact that changing to `waiting` removes any statuses + (upsert-exception! tx order-id order_date (:recurrence_exceptions/status exception))) + order-id)) + +(update-non-recurring db/db-uri (db/get-by-id db/db-uri 2 :orders 285) {:notes "asddqwqwd" :order_date "2020-04-19"}) +(recurrence-exception? db/db-uri 285 "2022-04-20") + +(defn upsert-order! [tx user-id customer-id {:keys [id day notes update-type order-date recurrence]}] + (let [updates (assoc? {:customer_id customer-id} + :recurrence recurrence + :notes notes + :order_date (some-> day t/to-db-date)) + order (db/get-by-id tx user-id :orders id)] + (cond + (not order) + (duplicate-order! tx user-id order updates) + + (-> order :orders/recurrence nil?) + (update-non-recurring tx order updates) + + (= :all update-type) + (do (sql/update! tx :orders (set-dates order updates) {:id id}) id) + + (= :from-here update-type) + (do + ;; TODO: update magic recurrence rules to handle splitting stuff here + (sql/update! tx :orders {:end_date (t/to-db-date order-date)} {:id id}) + (duplicate-order! tx user-id order updates)) + + :else ; single item modified + (do + (upsert-exception! tx id order-date "canceled") + (duplicate-order! tx user-id order updates))))) (defn structure-order [items] {:id (-> items first :orders/id) @@ -57,7 +126,7 @@ LEFT OUTER JOIN order_products op ON o.id = op.order_id LEFT OUTER JOIN products p on p.id = op.product_id ") -(def date-filter-clause "WHERE o.order_date >= ? AND o.end_date <= ? ") +(def date-filter-clause "WHERE o.end_date >= ? AND o.order_date <= ? ") (def orders-date-query (str orders-query date-filter-clause)) (defn- get-orders @@ -90,15 +159,14 @@ (group-by :day) (merge (reduce #(assoc %1 (t/format-date %2) {}) {} days))))) -(defn replace! [user-id {:keys [who products] :as order}] +(defn replace! [user-id {:keys [who products day order-date] :as order}] (jdbc/with-transaction [tx db/db-uri] (let [customer-id (or (:id who) - (customers/get-or-create-by-name tx user-id (:name who))) - previous-day (some->> order :id (db/get-by-id tx user-id :orders) :orders/order_date t/to-inst)] + (customers/get-or-create-by-name tx user-id (:name who)))] (products/update-products-mapping! tx user-id :order (upsert-order! tx user-id customer-id order) products) - (orders-for-days tx user-id previous-day (some-> order :day t/parse-date))))) + (orders-for-days tx user-id day order-date)))) (defn change-state! "Update the state of the given order and also modify the number of products available: @@ -118,35 +186,24 @@ [(str "UPDATE products SET amount = amount " operator " ? WHERE name = ?") amount (name prod)])) - ;; upsert the state for the given day - (if (jdbc/execute-one! tx - ["SELECT * from recurrence_exceptions WHERE order_id = ? AND order_date = ?" id (t/to-db-date day)]) - (sql/update! tx :recurrence_exceptions {:status (jdbc.types/as-other state)} - {:order_id id :order_date (t/to-db-date day)}) - (sql/insert! tx :recurrence_exceptions {:order_id id - :order_date (t/to-db-date day) - :status (jdbc.types/as-other state)}))) + (upsert-exception! tx id day state)) + (orders-for-days tx user-id day)))) -(defn delete! [user-id day id] +(defn- full-delete [tx user-id id] + (when-let [{:orders/keys [order_date end_date]} (some->> id (db/get-by-id tx user-id :orders))] + (sql/delete! tx :orders {:id id :user_id user-id}) + (orders-for-days tx user-id order_date end_date))) + +(defn delete! [user-id day action-type id] (jdbc/with-transaction [tx db/db-uri] - (if day - ;; Only delete the one day - (change-state! tx user-id id day "canceled") + (prn (->> id (db/get-by-id tx user-id :orders))) + (cond ;; Delete the order along with all recurrences - (when-let [{:orders/keys [order_date end_date]} (some->> id (db/get-by-id tx user-id :orders))] - (sql/delete! tx :orders {:id id :user_id user-id}) - (orders-for-days tx user-id order_date end_date))))) + (or (->> id (db/get-by-id tx user-id :orders) :orders/recurrence nil?) + (= :all action-type)) + (full-delete tx user-id id) -;; (delete! 2 "2022-04-20" 240) -;; (delete! 2 nil 241) - -;; (change-state! 2 240 "2022-04-20" "waiting") -;; (change-state! 2 250 "2022-04-23" "fulfilled") -;; (get-orders db/db-uri (t/to-inst #inst "2022-04-20T00:00:00Z") (t/to-inst #inst "2022-04-20T00:00:00Z") nil nil) -;; (get-orders db/db-uri (t/to-inst #inst "2022-04-23T00:00:00Z") (t/to-inst #inst "2022-04-24T00:00:00Z") nil nil) -;; (get-order db/db-uri 2 242 (t/to-inst #inst "2022-04-20T00:00:00Z")) -;; (orders-for-days db/db-uri 2 #inst "2022-04-23T00:00:00Z" #inst "2022-04-23T00:00:00Z") -;; (orders-for-days db/db-uri 2 #inst "2022-04-23T00:00:00Z") -;; (orders-for-days db/db-uri 2 "2022-04-19") -;; (get-all 2) + ;; Only delete the one day + :else + (change-state! tx user-id id day "canceled")))) diff --git a/backend/src/chicken_master/time.clj b/backend/src/chicken_master/time.clj index 64c59c4..548d16f 100644 --- a/backend/src/chicken_master/time.clj +++ b/backend/src/chicken_master/time.clj @@ -5,12 +5,6 @@ [org.dmfs.rfc5545.recur RecurrenceRule] [org.dmfs.rfc5545 DateTime])) -(defn recurrence->dates [start rule] - (let [iterator (.iterator (RecurrenceRule. rule) - (-> start (.toEpochMilli) (DateTime.)))] - (take-while identity - (repeatedly #(when (.hasNext iterator) - (-> iterator (.nextDateTime) (.getTimestamp) (Instant/ofEpochMilli))))))) (defn parse-date [date] (if (= (count date) 10) (-> date (LocalDate/parse) (.atStartOfDay) (.toInstant ZoneOffset/UTC)) @@ -56,4 +50,18 @@ (defn now [] (Instant/now)) (def min-date (parse-date "2020-01-01")) -(def max-date (.plusSeconds (now) (* 10 356 24 60 60))) ; 10 years from now - can't be bothered to do this properly... +(def max-date (.plusSeconds (now) (* 40 356 24 60 60))) ; 40 years from now - can't be bothered to do this properly... + +(defn recurrence->dates [start rule] + (let [iterator (.iterator (RecurrenceRule. rule) + (-> start (.toEpochMilli) (DateTime.)))] + (take-while identity + (repeatedly #(when (.hasNext iterator) + (-> iterator (.nextDateTime) (.getTimestamp) (Instant/ofEpochMilli))))))) + +(defn last-date + "Get the end date for the given rule" + [start rule] + (->> (recurrence->dates (to-inst start) rule) + (take-while #(before % max-date)) + last)) diff --git a/backend/test/chicken_master/orders_test.clj b/backend/test/chicken_master/orders_test.clj index e1ee467..10596ea 100644 --- a/backend/test/chicken_master/orders_test.clj +++ b/backend/test/chicken_master/orders_test.clj @@ -9,17 +9,17 @@ [clojure.string :as str] [clojure.test :refer [deftest is testing]])) -(defn raw-order-row [& {:keys [id notes status date user_id user_name products] +(defn raw-order-row [& {:keys [id notes status date user_id user_name products recurrence] :or {id 1 notes "note" status "pending" date #inst "2020-01-01" - user_id 2 user_name "mr blobby" + user_id 2 user_name "mr blobby" recurrence nil products {:eggs {:amount 12 :price nil} :milk {:amount 3 :price 423}}}}] (if products (for [[product {:keys [amount price]}] products] - (merge #:orders{:id id :notes notes :order_date date :end_date date} + (merge #:orders{:id id :notes notes :order_date date :end_date date :recurrence recurrence} #:recurrence_exceptions{:order_id id :order_date date :status status} #:customers{:id user_id :name user_name} {:products/name (name product) :order_products/price price :order_products/amount amount})) - [(merge #:orders{:id id :notes notes :order_date date :end_date date} + [(merge #:orders{:id id :notes notes :order_date date :end_date date :recurrence recurrence} #:recurrence_exceptions{:order_id id :order_date date :status status} #:customers{:id user_id :name user_name} {:products/name nil :order_products/price nil :order_products/amount nil})])) @@ -40,7 +40,7 @@ (deftest test-get-order (testing "correct values returned" (with-redefs [sql/query (fn [_ [query & params]] - (is (str/ends-with? query "WHERE o.order_date >= ? AND o.end_date <= ? AND o.id = ? AND o.user_id = ?")) + (is (str/ends-with? query "WHERE o.end_date >= ? AND o.order_date <= ? AND o.id = ? AND o.user_id = ?")) (is (= params [(t/to-db-date t/min-date) (t/to-db-date t/max-date) 123 "1"])) (raw-order-row))] (is (= (sut/get-order :tx "1" 123) @@ -50,7 +50,7 @@ (testing "Only 1 item returned" (with-redefs [sql/query (fn [_ [query & params]] - (is (str/ends-with? query "WHERE o.order_date >= ? AND o.end_date <= ? AND o.id = ? AND o.user_id = ?")) + (is (str/ends-with? query "WHERE o.end_date >= ? AND o.order_date <= ? AND o.id = ? AND o.user_id = ?")) (is (= params [(t/to-db-date t/min-date) (t/to-db-date t/max-date) 123 "1"])) (concat (raw-order-row) (raw-order-row :id 21)))] @@ -62,7 +62,7 @@ (deftest test-get-all (testing "correct values returned" (with-redefs [sql/query (fn [_ [query & params]] - (is (str/ends-with? query "WHERE o.order_date >= ? AND o.end_date <= ? AND o.user_id = ?")) + (is (str/ends-with? query "WHERE o.end_date >= ? AND o.order_date <= ? AND o.user_id = ?")) (is (= params [(t/to-db-date t/min-date) (t/to-db-date t/max-date) "1"])) (concat (raw-order-row :id 1 :status "waiting") @@ -126,13 +126,15 @@ sql/query (constantly (concat (raw-order-row :id 1 :status "waiting" :date #inst "2020-01-02") (raw-order-row :id 4)))] - (is (= (sut/replace! :user-id order) - {"2020-01-01" [{:id 4, :notes "note", :state :pending, :day "2020-01-01", - :who {:id 2, :name "mr blobby"}, :recurrence nil - :products {:eggs {:amount 12 :price nil} :milk {:amount 3 :price 423}}}] - "2020-01-02" [{:id 1, :notes "note", :state :waiting, :day "2020-01-02", - :who {:id 2, :name "mr blobby"}, :recurrence nil - :products {:eggs {:amount 12 :price nil} :milk {:amount 3 :price 423}}}]}))))) + (is (= {"2020-01-02" [{:id 1, :notes "note", :recurrence nil, + :who {:id 2, :name "mr blobby"}, + :day "2020-01-02", :state :waiting + :products {:eggs {:amount 12, :price nil}, :milk {:amount 3, :price 423}},} + {:id 4, :notes "note", :recurrence nil, + :who {:id 2, :name "mr blobby"}, + :day "2020-01-02", :state :waiting + :products {:eggs {:amount 12, :price nil}, :milk {:amount 3, :price 423}}}]} + (sut/replace! :user-id order)))))) (testing "unknown products are ignored" (let [order {:id 1, :notes "note", :state :waiting, :day "2020-01-01", @@ -167,7 +169,7 @@ (is (= table :orders)) (is (= by {:id 1 :user_id :user-id}))) sql/query (constantly (raw-order-row :id 4))] - (is (= (sut/delete! :user-id nil 1) + (is (= (sut/delete! :user-id nil nil 1) {"2020-01-01" [{:id 4, :notes "note", :state :pending, :day "2020-01-01", :who {:id 2, :name "mr blobby"}, :recurrence nil :products {:eggs {:amount 12 :price nil} :milk {:amount 3 :price 423}}}]})))) @@ -179,48 +181,90 @@ (is (= table :orders)) (is (= by {:id 1 :user_id :user-id}))) sql/query (constantly (raw-order-row :id 4))] - (is (nil? (sut/delete! :user-id nil 1))))) - - (let [invocations (atom [])] - (with-redefs [jdbc.types/as-other identity - jdbc/transact (fn [_ f & args] (apply f args)) - jdbc/execute-one! (constantly {:orders/order_date #inst "2020-01-01"}) - sql/delete! (fn [_ table by] - (swap! invocations conj ["deleting" table by])) - sql/query (constantly (raw-order-row :id 4)) - sql/update! (fn [_ table status key] (swap! invocations conj ["updating" table status key])) - sql/insert! (fn [_ table values] (swap! invocations conj ["inserting" table values]))] - (testing "deleting without provided a date will remove the whole order" - (reset! invocations []) - (is (= (sut/delete! :user-id nil 1) - {"2020-01-01" [{:id 4, :notes "note", :state :pending, :day "2020-01-01", - :who {:id 2, :name "mr blobby"}, :recurrence nil - :products {:eggs {:amount 12 :price nil} :milk {:amount 3 :price 423}}}]})) - (is (= [["deleting" :orders {:id 1 :user_id :user-id}]] - @invocations))) - - (testing "deleting with a provided date will soft remove a single order by updating it if it exists" - (reset! invocations []) - (is (= (sut/delete! :user-id "2020-01-01" 1) - {"2020-01-01" [{:id 4, :notes "note", :state :pending, :day "2020-01-01", - :who {:id 2, :name "mr blobby"}, :recurrence nil - :products {:eggs {:amount 12 :price nil} :milk {:amount 3 :price 423}}}]})) - (is (= [["updating" :recurrence_exceptions {:status "canceled"} - {:order_id 1, :order_date (t/to-db-date "2020-01-01")}]] - @invocations))) - - (testing "deleting with a provided date will soft remove a single order by adding an exception if none provided" - (with-redefs [jdbc/execute-one! (fn [_ [q]] - (when-not (str/includes? q "recurrence_exceptions") - {:orders/order_date #inst "2020-01-01"}))] + (is (nil? (sut/delete! :user-id nil nil 1))))) + (testing "non recurrence items" + (let [invocations (atom [])] + (with-redefs [jdbc.types/as-other identity + jdbc/transact (fn [_ f & args] (apply f args)) + jdbc/execute-one! (constantly {:orders/order_date #inst "2020-01-01"}) + sql/delete! (fn [_ table by] + (swap! invocations conj ["deleting" table by])) + sql/query (constantly (raw-order-row :id 4)) + sql/update! (fn [_ table status key] (swap! invocations conj ["updating" table status key])) + sql/insert! (fn [_ table values] (swap! invocations conj ["inserting" table values]))] + (testing "deleting without provided a date will remove the whole order" (reset! invocations []) - (is (= (sut/delete! :user-id "2020-01-01" 1) + (is (= (sut/delete! :user-id nil nil 1) {"2020-01-01" [{:id 4, :notes "note", :state :pending, :day "2020-01-01", :who {:id 2, :name "mr blobby"}, :recurrence nil :products {:eggs {:amount 12 :price nil} :milk {:amount 3 :price 423}}}]})) - (is (= [["inserting" :recurrence_exceptions {:order_id 1, :order_date (t/to-db-date "2020-01-01") :status "canceled"}]] - @invocations))))))) + (is (= [["deleting" :orders {:id 1 :user_id :user-id}]] + @invocations))) + + (testing "a provided date is ignored and will full delete" + (reset! invocations []) + (is (= (sut/delete! :user-id "2020-01-01" nil 1) + {"2020-01-01" [{:id 4, :notes "note", :state :pending, :day "2020-01-01", + :who {:id 2, :name "mr blobby"}, :recurrence nil + :products {:eggs {:amount 12 :price nil} :milk {:amount 3 :price 423}}}]})) + (is (= [["deleting" :orders {:id 1 :user_id :user-id}]] + @invocations))) + + (testing "action-type is ignored and will full delete" + (with-redefs [jdbc/execute-one! (fn [_ [q]] + (when-not (str/includes? q "recurrence_exceptions") + {:orders/order_date #inst "2020-01-01"}))] + + (reset! invocations []) + (is (= (sut/delete! :user-id "2020-01-01" :single 1) + {"2020-01-01" [{:id 4, :notes "note", :state :pending, :day "2020-01-01", + :who {:id 2, :name "mr blobby"}, :recurrence nil + :products {:eggs {:amount 12 :price nil} :milk {:amount 3 :price 423}}}]})) + (is (= [["deleting" :orders {:id 1 :user_id :user-id}]] + @invocations))))))) + + (testing "recurrence items" + (let [invocations (atom [])] + (with-redefs [jdbc.types/as-other identity + jdbc/transact (fn [_ f & args] (apply f args)) + jdbc/execute-one! (constantly {:orders/order_date #inst "2020-01-01" :orders/recurrence "FREQ=DAILY;COUNT=1"}) + sql/delete! (fn [_ table by] + (swap! invocations conj ["deleting" table by])) + sql/query (constantly (raw-order-row :id 4 :recurrence "FREQ=DAILY;COUNT=1")) + sql/update! (fn [_ table status key] (swap! invocations conj ["updating" table status key])) + sql/insert! (fn [_ table values] (swap! invocations conj ["inserting" table values]))] + (testing "deleting with :all remove the whole order" + (reset! invocations []) + (is (= (sut/delete! :user-id nil :all 1) + {"2020-01-01" [{:id 4, :notes "note", :state :pending, :day "2020-01-01", + :who {:id 2, :name "mr blobby"}, :recurrence "FREQ=DAILY;COUNT=1" + :products {:eggs {:amount 12 :price nil} :milk {:amount 3 :price 423}}}]})) + (is (= [["deleting" :orders {:id 1 :user_id :user-id}]] + @invocations))) + + (testing "deleting with a provided date will soft remove a single order by updating it if it exists" + (reset! invocations []) + (is (= (sut/delete! :user-id "2020-01-01" nil 1) + {"2020-01-01" [{:id 4, :notes "note", :state :pending, :day "2020-01-01", + :who {:id 2, :name "mr blobby"}, :recurrence "FREQ=DAILY;COUNT=1" + :products {:eggs {:amount 12 :price nil} :milk {:amount 3 :price 423}}}]})) + (is (= [["updating" :recurrence_exceptions {:status "canceled"} + {:order_id 1, :order_date (t/to-db-date "2020-01-01")}]] + @invocations))) + + (testing "deleting with a provided date will soft remove a single order by adding an exception if none provided" + (with-redefs [jdbc/execute-one! (fn [_ [q]] + (when-not (str/includes? q "recurrence_exceptions") + {:orders/order_date #inst "2020-01-01" :orders/recurrence "FREQ=DAILY;COUNT=1"}))] + + (reset! invocations []) + (is (= (sut/delete! :user-id "2020-01-01" nil 1) + {"2020-01-01" [{:id 4, :notes "note", :state :pending, :day "2020-01-01", + :who {:id 2, :name "mr blobby"}, :recurrence "FREQ=DAILY;COUNT=1" + :products {:eggs {:amount 12 :price nil} :milk {:amount 3 :price 423}}}]})) + (is (= [["inserting" :recurrence_exceptions {:order_id 1, :order_date (t/to-db-date "2020-01-01") :status "canceled"}]] + @invocations)))))))) (deftest test-change-state! (let [updates (atom [])] diff --git a/frontend/src/chicken_master/calendar.cljs b/frontend/src/chicken_master/calendar.cljs index 74e93df..eb9db53 100644 --- a/frontend/src/chicken_master/calendar.cljs +++ b/frontend/src/chicken_master/calendar.cljs @@ -86,7 +86,9 @@ (defn format-order [settings {:keys [id who day hour notes state products]}] [:div {:class [:order state] :key (gensym) :draggable true - :on-drag-start #(-> % .-dataTransfer (.setData "text" id))} + :on-drag-start (fn [e] + (-> e .-dataTransfer (.setData "order-day" day)) + (-> e .-dataTransfer (.setData "order-id" id)))} [:div {:class :actions} (condp = state :waiting [:button {:on-click #(re-frame/dispatch [::event/fulfill-order id day])} "✓"] @@ -97,7 +99,7 @@ [:button {:on-click #(re-frame/dispatch [::event/confirm-action "na pewno usunąć?" - ::event/remove-order id])} "-"]] + ::event/remove-order id day])} "-"]] [:div {:class :who} (:name who)] (if (settings :show-order-time) [:div {:class :when} hour]) @@ -111,9 +113,10 @@ (let [orders (map calc-order-prices orders)] [:div {:class [:day (when (-> date time/parse-date time/today?) :today)] :on-drag-over #(.preventDefault %) - :on-drop #(let [id (-> % .-dataTransfer (.getData "text") prod/num-or-nil)] + :on-drop #(let [id (-> % .-dataTransfer (.getData "order-id") prod/num-or-nil) + from (-> % .-dataTransfer (.getData "order-day"))] (.preventDefault %) - (re-frame/dispatch [::event/move-order id date]))} + (re-frame/dispatch [::event/move-order id from date]))} [:div {:class :day-header} (-> date time/parse-date time/format-date)] [:div [:div {:class :orders} diff --git a/frontend/src/chicken_master/events.cljs b/frontend/src/chicken_master/events.cljs index 8d0eb78..ddfc012 100644 --- a/frontend/src/chicken_master/events.cljs +++ b/frontend/src/chicken_master/events.cljs @@ -77,15 +77,18 @@ (re-frame/reg-event-fx ::remove-order - (fn [_ [_ id]] - {:http-xhrio (http-request :delete (str "orders/" id))})) + (fn [_ [_ id day action-type]] + (if (or day action-type) + {:http-xhrio (http-request :post (str "orders/" id "/remove") + :body {:day day :action-type action-type})} + {:http-xhrio (http-request :delete (str "orders/" id))}))) (re-frame/reg-event-fx ::move-order - (fn [{{orders :orders} :db} [_ id day]] + (fn [{{orders :orders} :db} [_ id from to]] {:http-xhrio (http-request :put (str "orders/" id) - :body (-> id orders (assoc :day day)))})) + :body (-> id orders (assoc :order-date from :day to)))})) (re-frame/reg-event-db ::edit-order @@ -93,7 +96,7 @@ (assoc db :order-edit (-> orders (get id {:state :waiting}) - (merge {:show true :day day}))))) + (merge {:show true :day day :order-date day}))))) (re-frame/reg-event-fx ::fulfill-order @@ -115,7 +118,7 @@ {:dispatch [::hide-modal :order-edit] :http-xhrio (http-post "orders" (merge - (select-keys order [:id :day :hour :state]) + (select-keys order [:id :day :hour :state :order-date]) (select-keys form [:id :day :hour :state :who :notes :products])))})) (re-frame/reg-event-fx