|
- #|
-
- src/web/inventory.lisp
-
- Crystal Commerce-style Inventory Management User Interface and helpers.
-
- TODO pass over the results of (make-search-query) such that
- :total-qty is the aggregate of:
-
- (select 'ygo-cc-item (where (:= :item_id xxx)))
-
- (reduce #'+
- (mapcar (alexandria:compose #'read-from-string #'cc-sell-price-of)
- (retrieve-dao 'ygo-cc-item :item-id 48883)))
-
- (reduce #'+ (mapcar #'cc-qty-of (retrieve-dao 'ygo-cc-item :item-id 48883)))
-
-
- |#
-
- (in-package #:cl-deck-builder2.web)
-
- (defun render-results (&key (active "/inventory") (class 'cc-item) (params nil) (tpl #P"inventory/search-results.html"))
- "Mega helper function. Render function for anything that currently queries the databse. We search both PRODUCT-NAME and NAME, as well as querying a list of VARIANTs, with a LIMIT on the number of results and an OFFSET into those search results. You may also specify a DIRECTION, and SORT-BY options.
-
- TODO Major rewrite candidate right here.
- TODO Integrate new SEARCH-SESSION object after that's done."
- (let ((direction (or (query-param "direction" params) "desc"))
- (variant (or (query-param "variant" params)
- (find-dao 'variant-condition :name "Near Mint")))
- (variants (select-variant-condition))
- (limit (or (query-param "limit" params) "10"))
- (name (or
- (query-param "name" params)
- (query-param "product-name" params)))
- (offset (or (query-param "offset" params) "0"))
- (sort-by (or (query-param "sort-by" params) "id")))
- (handler-case
- (ratify:with-parsed-forms
- ((:integer limit)
- (:integer offset)
- (:string direction)
- (:string sort-by))
- ;; NAME can be blank, so...
- (let* ((filtered-cards (make-search-query class params))
- (length (make-count-query class params))
- (pages (generate-pages length offset limit)))
- (render-with-env tpl
- `(:active ,active
- :cards ,filtered-cards
- :direction ,direction
- :last-page ,(car (last pages))
- :length ,length
- :limit ,limit
- :name ,name
- :offset ,offset
- :opposite-direction ,(get-opposite-direction direction)
- :pages ,pages
- :search-params ,+search-params+
- :sort-by ,sort-by
- :total ,(count-dao class)
- :variant ,variant
- :variants ,variants))))
- (ratify:combined-error (e)
- (flash-error (format nil "~a/search.error => ~a~%" active e))))))
-
- ;; USE REINITIALIZE-INSTANCE to update the existing YGO-SET-ITEM from _PARSED
- (defun patch-card (card _parsed)
- (let ((set-id (query-param "set-id" card))
- (variant-id (query-param "variant-id" card)))
- (handler-case
- (ratify-parsing:with-parsed-forms
- ((:integer set-id)
- (:integer variant-id))
- (let ((found (find-or-create-instance 'ygo-set-item :item-id set-id :variant-id variant-id))
- (clean (filter-alist _parsed)))
- (v:info :inventory "PATCH-CARD: ~a" found)
- (if found
- ;; TODO redraw item based on context? Like patching from the inventory list vs patching from the editor?
- ;; (redirect (format nil "/inventory/~d/edit" (mito:object-id found)) 303)
- (progn
- (apply #'reinitialize-instance found (assoc-utils:alist-plist clean))
- (update-dao found)
- (_ "Save"))
- (progn
- (flash-error (format nil "Error udpating id ~d:~d" set-id variant-id))))))
- (ratify:combined-error (e)
- (flash-error e)))))
-
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;; Inventory Viewer
- (defroute ("/inventory" :method :GET) (&key _parsed)
- "Inventory Viewer GET route. Will display index with search results."
- (v:info :inventory "GET /inventory ~a" _parsed)
-
- ;; (with-logged-in-user
- ;; (render-results :params _parsed :tpl #P"inventory/index.html"))
- (redirect "/cards"))
-
- #|
- (defroute ("/inventory" :method :POST) (&key _parsed)
- "Inventory Viewer search POST route. Will display index with search results."
- (v:info :inventory "POST /inventory ~a" _parsed)
-
- (with-logged-in-user
- (render-results :params _parsed :tpl #P"inventory/index.html")))
-
- (defroute ("/inventory/search" :method :POST) (&key _parsed)
- "Inventory Viewer search POST route. Will display index with search results."
- (v:info :inventory "POST /inventory/search ~a" _parsed)
-
- (with-logged-in-user
- (render-results :params _parsed)))
-
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;; Inventory Item Editor
- ;;
- ;; TODO PUT?? POST?? GET??
-
- ;; New Item
- (defroute ("/inventory/new" :method :GET) ()
- "Display the page for creation of a new inventory item"
- (v:info :inventory "GET /inventory/new")
-
- (with-logged-in-user
- (render-with-env #P"inventory/new.html"
- `(:active "/inventory"
- :card ,(make-instance 'cc-item)))))
-
- (defroute ("/inventory/new" :method :POST) (&key _parsed)
- "POST method for the processing the information from page for creation of a new inventory item."
- (v:info :inventory "POST /inventory/new => ~a" _parsed)
-
- (with-logged-in-user
- (let ((clean (filter-alist _parsed)))
- (let ((new (apply #'cc-create (assoc-utils:alist-plist clean))))
- (when (mito:object-id new)
- (redirect (format nil "/inventory/~d/edit" (mito:object-id new))))))))
-
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;; Inventory Item Importer
- (defroute ("/inventory/import" :method :GET) ()
- "Inventory Item Importer. TODO"
- (v:info :inventory "GET /inventory/import")
-
- (with-logged-in-user
- (render-with-env #P"inventory/import.html"
- `(:active "/inventory"))))
-
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;; Seems like this one needs to be last. It has something to do with
- ;; the wildcard :ID parameter. Maybe we ought to add the /edit back?
-
- (defroute ("/inventory/:id/edit" :method :GET) (&key id)
- "Edit Route for Inventory Item.
-
- ARGUMENTS
- ID The ID of the CC-ITEM inventory item you wish to edit."
- (v:info :inventory "GET /inventory/~d/edit" id)
-
- (with-logged-in-user
- (handler-case
- (ratify-parsing:with-parsed-forms
- ((:integer id))
- (render-with-env #P"inventory/edit.html"
- `(:active "/inventory"
- :errors ,(flash-gethash :errors)
- :messages ,(flash-gethash :messages)
- :card ,(cc-select-by-id id))))
- (ratify:combined-error (e)
- (flash-error e)))))
-
- (defroute ("/inventory/:id/edit" :method :POST) (&key id _parsed)
- "CC-ITEM Update POST route. If the item exists, update it using REINITIALIZE-INSTANCE, after filtering _PARSED through FILTER-ALIST.
-
- TODO Differentiate between CC-ITEM and YGO-CC-ITEM?"
- (v:info :inventory "POST /inventory/~d/edit => ~a" id _parsed)
-
- (with-logged-in-user
- (handler-case
- (ratify-parsing:with-parsed-forms
- ((:integer id))
- (with-connection (db)
- (let ((found (mito:find-dao 'cc-item :id id))
- (clean (filter-alist _parsed)))
- (when found
- (apply #'reinitialize-instance found (assoc-utils:alist-plist clean))
- (mito:save-dao found)
- (redirect (format nil "/inventory/~d/edit" (mito:object-id found)) 303)))))
- (ratify:combined-error (e)
- (flash-error e)))))
-
- (defroute ("/inventory/:id/delete" :method :DELETE) (&key id)
- "DELETE an Inventory Item specified by ID."
- (v:info :inventory "DELETE /inventory/~d/delete" id)
-
- (with-logged-in-user
- (handler-case
- (ratify-parsing:with-parsed-forms
- ((:integer id))
- (cc-delete-by-id id))
- (ratify:combined-error (e)
- (flash-error e)))))
- |#
-
- (defroute ("/inventory/patch" :method :PATCH) (&key _parsed)
- "YGO-CC-ITEM PATCH route. This appears to be functionally identical to EDIT route for ID, but this is using YGO-CC-ITEM as class. The POST route appears to be used for CC-ITEM object."
- (v:info :inventory "PATCH /inventory/patch => ~a" _parsed)
-
- (with-logged-in-user
- (alexandria:if-let ((cards (query-param "cards" _parsed)))
- (dolist (card cards)
- (patch-card card _parsed))
- (patch-card _parsed _parsed))))
-
- ;; Huh? It works??
- (defroute ("/inventory/variants/:id" :method :GET) (&key id)
- "Display the VARIANTs for this inventory item using SELECT-YGO-CC-ITEM-VARIANTS."
- (v:info :inventory "GET /inventory/variants/~d" id)
-
- (with-logged-in-user
- (handler-case
- (ratify-parsing:with-parsed-forms
- ((:integer id))
- (render-with-env #P"inventory/variant-results.html"
- (list :active "/inventory"
- :id id
- :cards (select-ygo-cc-item-variants id))))
- ;; :cards ,filtered-cards
- ;; :variant ,variant
- ;; :variants ,variants
- ;; :direction ,direction
- ;; :length ,length
- ;; :total ,(count-dao class)
- ;; :limit ,limit
- ;; :name ,name
- ;; :offset ,offset
- ;; :opposite-direction ,(get-opposite-direction direction)
- ;; :pages ,(generate-pages length offset limit)
- ;; :search-params ,+search-params+
- ;; :sort-by ,sort-by)
-
- (ratify:combined-error (e)
- (flash-error e)))))
|