Files
shop-go/internal/handlers/customer_product.go
T

163 lines
4.2 KiB
Go

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))
}