Skip to content

Instantly share code, notes, and snippets.

@sventech
Last active June 24, 2016 20:55
Show Gist options
  • Save sventech/cdc4f0a662192980dd03 to your computer and use it in GitHub Desktop.
Save sventech/cdc4f0a662192980dd03 to your computer and use it in GitHub Desktop.
Clojure parser for SimpleCart(js) form POST/GET
(ns webstore.simplecart_parser
(:require [clojure.string :as string]))
;; see github.com/sventech/simplecart-js for tax calculation improvement fork
(def input-params
{"item_quantity_1" "1",
"itemCount" "2",
"item_price_1" "9.99",
"store_name" "Online Store",
"item_name_1" "Awesome Product - MP3",
"currency" "USD",
"taxCountry" "US",
"return" "/success",
"item_quantity_2" "1",
"invoiceNumber" "ABC-123456789",
"item_options_1" "artist: Family Band, number: ZH15862-MP3, physical: 0, weight: 0",
"taxRate" "0.07",
"cart_id" "12345",
"item_name_2" "Excellent Title - CD",
"taxRegion" "North Carolina",
"item_price_2" "9.99",
"item_options_2" "artist: New Band, number: XT13232-CD, physical: 1, weight: 0.3",
"shipping" "0",
"tax" "0",
"cancel_return" "/cancel"})
;; shopping cart handling -- special thanks to Sean Omlor of Asheville Coder's league
(def cart-keys [:taxRegion :taxCountry :taxRate :tax :cart_id :itemCount
:currency :store_name :shipping :invoiceNumber])
(def item-keys
[:item_name :item_options :item_quantity :item_price])
(defn one-to-n [n]
(map inc (take n (range))))
(defn clean-key [key]
(keyword (clojure.string/replace (name key) #"_\d+" "")))
(defn keys-for-num [item-num]
(map #(keyword (str (name %) "_" item-num)) item-keys))
(defn num-items [items]
(Integer/parseInt (:itemCount items)))
;; convert "artist: New Band, number: XT13232-CD, physical: 1, weight: 0"
;; into {:item_artist "New Band", :item_number "XT13232-CD", :item_physical "1", :item_weight "0"}
(defn parse-options
"Convert 'options' entry into multiple entries for item"
[option-string]
(let [option-list (string/split option-string #", ")]
(let [option-seq (map #(string/split % #": ") option-list)]
(into {}
(for [[k v] option-seq]
[(keyword (str "item_" k)) v])))))
(defn parse-items [item-map]
"Break items by key like ':item_foo_1' into vector of maps"
(into []
(map #(merge % (parse-options (:item_options %)))
(for [item-num (one-to-n (num-items item-map))]
(reduce-kv (fn [m k v] (assoc m (clean-key k) v)) {}
(select-keys item-map (keys-for-num item-num)))))))
;; keywordize string map, then separate cart-global keys from items
(defn parse-cart
"Get clean map from shopping cart param POST"
[param-map]
(let [in-map (clojure.walk/keywordize-keys param-map)]
(assoc (select-keys in-map cart-keys)
:items (parse-items in-map))))
@JonathanGTH
Copy link

Thank You, Much appreciated

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment