(import-macros {:compile-html HTML} :macros) (local forms (require :forms)) (local lib (require :lib)) (local shop (require :shop)) (local templates (require :templates)) (local order-form [{:title "" :fields [ (forms.text-input "name" "Как к вам обращаться?" true) (forms.text-input "contact" "Телеграм или E-mail для связи" true) (forms.checkbox-input "correct-order" "Данные заказа верны" true) (forms.checkbox-input "consent" (.. "Я даю согласие ИП «Горенкин Владислав Константинович» (ИНН ...)" " на хранение и обработку предоставленных персональных данных для уточнения деталей заказа.") true)]}]) (fn content-template [db basket data errors] [(HTML [:aside {} (templates.header "/shop/order") (if (< 0 (# basket)) (templates.basket basket "/shop/order") "")]) (HTML [:div {:class "content"} [:div {:class "back"} [:a {:href "/shop"} "⟵ Обратно к списку"]] [:section {} [:h2 {} "Оформление заказа"] (forms.render-form order-form data errors)]])]) (fn check-stocks [db basket] (var error nil) (each [_ line (ipairs basket) &until error] (local product (. (_G.must (luna.db.query-assoc db "SELECT title, stock FROM products WHERE name = ?" [line.name])) 1)) (when (< (- product.stock line.quantity) 0) (set error (.. "К сожалению, товар «" product.title "» закончился." " Пожалуйста, уберите его из корзины и попробуйте оформить заказ снова.")))) error) (fn render [request db] (let [order-id (shop.order-id request) basket (if order-id (shop.basket db order-id) [])] (if (= request.method "POST") (let [data (forms.html-form->data order-form request.form) stock-error (check-stocks db basket)] (if (not stock-error) (do (shop.place-order db order-id data.name data.contact data.consent) (lib.notify (.. "Новый заказ " "" order-id " от " data.name ".\n\n" "Список заказов")) ;; redirect and clear order cookie (values 302 {:Location (.. "/shop/order/" order-id) :Set-Cookie "order=; Path=/; Expires=Thu, 01 Jan 1970 00:00:00 GMT"} "")) (values 400 {} (templates.base (content-template db basket data {:consent stock-error}))))) (if (< 0 (# basket)) (values 200 {} (templates.base (content-template db basket {} {}))) (values 302 {:Location "/shop"} ""))))) {: render}