package handlers import ( "log" "net/http" "strconv" "time" "shop/internal/auth" "shop/internal/compare" "shop/internal/models" ) func (h *CustomerHandler) BuyNow(w http.ResponseWriter, r *http.Request) { if err := r.ParseForm(); err != nil { http.Error(w, "Bad Request", http.StatusBadRequest) return } productID, _ := strconv.Atoi(r.FormValue("product_id")) qty, _ := strconv.Atoi(r.FormValue("quantity")) if qty < 1 { qty = 1 } if productID <= 0 { http.Redirect(w, r, "/", http.StatusSeeOther) return } cartID, err := h.resolveCart(r, w) if err == nil { _ = h.cart.AddItem(r.Context(), cartID, productID, qty) } http.Redirect(w, r, "/checkout", http.StatusSeeOther) } func (h *CustomerHandler) ProductReserve(w http.ResponseWriter, r *http.Request) { if err := r.ParseForm(); err != nil { http.Error(w, "Bad Request", http.StatusBadRequest) return } id, err := strconv.Atoi(r.PathValue("id")) if err != nil { http.NotFound(w, r) return } ctx := r.Context() if _, err := h.products.GetActiveByID(ctx, id); err != nil { http.NotFound(w, r) return } sessionKey := h.cartSession.EnsureKey(w, r) if active, err := h.reservations.ActiveByProduct(ctx, id); err == nil { if active.SessionKey != sessionKey { var uid int if u, ok := auth.UserIDFromSession(h.userSession, r); ok { uid = u } if active.UserID == nil || uid == 0 || *active.UserID != uid { http.Redirect(w, r, "/product/"+strconv.Itoa(id)+"?err=reserved", http.StatusSeeOther) return } } } name := r.FormValue("name") phone := r.FormValue("phone") if uid, ok := auth.UserIDFromSession(h.userSession, r); ok { if u, err := h.users.GetByID(ctx, uid); err == nil { if name == "" { name = u.Name } if phone == "" { phone = u.Phone } } } if name == "" { name = "Гость" } res := models.Reservation{ ProductID: id, SessionKey: sessionKey, CustomerName: name, CustomerPhone: phone, ExpiresAt: time.Now().Add(h.reservations.ExpiresIn()), } if uid, ok := auth.UserIDFromSession(h.userSession, r); ok { res.UserID = &uid } if err := h.reservations.ReplaceForProduct(ctx, &res); err != nil { log.Printf("reserve: %v", err) http.Redirect(w, r, "/product/"+strconv.Itoa(id), http.StatusSeeOther) return } http.Redirect(w, r, "/product/"+strconv.Itoa(id)+"?ok=reserve", http.StatusSeeOther) } func (h *CustomerHandler) CompareAdd(w http.ResponseWriter, r *http.Request) { if err := r.ParseForm(); err != nil { http.Error(w, "Bad Request", http.StatusBadRequest) return } productID, _ := strconv.Atoi(r.FormValue("product_id")) otherID, _ := strconv.Atoi(r.FormValue("other_id")) redirect := r.FormValue("redirect") if redirect == "" { redirect = "/compare" } raw, _ := h.compareSession.FromRequest(r) next := raw if productID > 0 { next = compare.Add(next, productID) } if otherID > 0 { next = compare.Add(next, otherID) } if next == raw && productID <= 0 { http.Redirect(w, r, redirect, http.StatusSeeOther) return } token, _ := h.compareSession.Create(next) h.compareSession.SetCookie(w, r, token) http.Redirect(w, r, redirect, http.StatusSeeOther) } func (h *CustomerHandler) CompareRemove(w http.ResponseWriter, r *http.Request) { if err := r.ParseForm(); err != nil { http.Error(w, "Bad Request", http.StatusBadRequest) return } productID, _ := strconv.Atoi(r.FormValue("product_id")) raw, _ := h.compareSession.FromRequest(r) next := compare.Remove(raw, productID) token, _ := h.compareSession.Create(next) h.compareSession.SetCookie(w, r, token) http.Redirect(w, r, "/compare", http.StatusSeeOther) } func (h *CustomerHandler) ComparePage(w http.ResponseWriter, r *http.Request) { raw, _ := h.compareSession.FromRequest(r) ids := compare.Parse(raw) ctx := r.Context() var products []models.Product for _, id := range ids { if p, err := h.products.GetActiveByID(ctx, id); err == nil { products = append(products, p) } } p := comparePage{ shopPage: h.basePage(r, w, "Сравнение товаров"), Products: products, } h.render(w, "compare.html", p) } func (h *CustomerHandler) compareCount(r *http.Request) int { raw, _ := h.compareSession.FromRequest(r) return len(compare.Parse(raw)) }