allow finalizing orders

This commit is contained in:
2025-03-25 20:36:28 +01:00
parent 30b32a571c
commit 854573eb3a
6 changed files with 360 additions and 88 deletions

View File

@@ -34,14 +34,6 @@ func NewCartItemController() CartItemController {
return &cartItemController{}
}
func GetShippingMethods() []models.Shipping {
return []models.Shipping{
{Id: "germany", Name: "Germany (DHL)", Price: 3.99},
{Id: "international", Name: "International (DHL)", Price: 5.99},
{Id: "pickup", Name: "Pickup", Price: 0.00},
}
}
func generateSessionId(length int) string {
bytes := make([]byte, length) // 16 bytes = 128 bits
_, err := rand.Read(bytes)
@@ -63,7 +55,7 @@ func GetSessionId(ctx *gin.Context) string {
}
func GenerateToken() string {
return generateSessionId(8)
return generateSessionId(16)
}
func (rc *cartItemController) NewCartItemFromForm(ctx *gin.Context) (models.CartItem, error) {
@@ -143,7 +135,7 @@ func (rc *cartItemController) NewAddressFromForm(ctx *gin.Context) (models.Addre
func (rc *cartItemController) NewOrderFromForm(ctx *gin.Context) (models.Order, error) {
sessionId := GetSessionId(ctx)
status := models.OrderStatus("Received")
status := models.OrderStatus("AwaitingConfirmation")
token := GenerateToken()
email := ctx.PostForm("email")
comment := ctx.PostForm("comment")
@@ -162,14 +154,9 @@ func (rc *cartItemController) NewOrderFromForm(ctx *gin.Context) (models.Order,
// }
//}
var shipping models.Shipping
for _, shippingMethod := range GetShippingMethods() {
if shippingMethod.Id == shippingStr {
shipping = shippingMethod
}
}
shipping, err := models.GetShippingMethod(shippingStr)
if shipping == (models.Shipping{}) {
if err != nil {
return models.Order{}, fmt.Errorf("Invalid shipping method.")
}
@@ -267,7 +254,7 @@ func (rc *cartItemController) CartItemView(c *gin.Context) {
data := CreateSessionData(c, gin.H{
"cartItems": cartItems,
"priceTotal": fmt.Sprintf("%.2f", priceTotal), //round 2 decimals
"shipping": GetShippingMethods(),
"shipping": models.GetShippingMethods(),
})
c.HTML(http.StatusOK, "cart.html", data)
@@ -348,6 +335,11 @@ func (rc *cartItemController) EditItemHandler(c *gin.Context) {
func (rc *cartItemController) CheckoutView(c *gin.Context) {
shippingMethod := c.Query("shippingMethod")
if shippingMethod == "" {
rc.CartItemView(c)
return
}
c.HTML(http.StatusOK, "checkout.html", gin.H{
"askAddress": (shippingMethod != "pickup"),
"shippingMethod": shippingMethod,
@@ -366,10 +358,8 @@ func (rc *cartItemController) CheckoutHandler(c *gin.Context) {
existingOrder, err := repositories.Orders.GetBySession(order.SessionId)
if errors.Is(err, gorm.ErrRecordNotFound) {
fmt.Println("CREATE")
_, err = repositories.Orders.Create(order)
} else if err == nil {
fmt.Println("UPDATE")
order.ID = existingOrder.ID
order.CreatedAt = existingOrder.CreatedAt
repositories.Orders.Update(order)
@@ -385,19 +375,27 @@ func (rc *cartItemController) CheckoutHandler(c *gin.Context) {
return
}
var shipping models.Shipping
for _, shippingMethod := range GetShippingMethods() {
if shippingMethod.Id == order.Shipping {
shipping = shippingMethod
}
shipping, err := models.GetShippingMethod(order.Shipping)
if err != nil {
data := CreateSessionData(c, gin.H{
"error": err,
"success": "",
})
c.HTML(http.StatusOK, "cart.html", data)
return
}
priceProducts := 0.0
for _, cartItem := range order.CartItems {
priceProducts += (float64(cartItem.Quantity) * cartItem.ItemVariant.Price)
}
priceProducts, priceTotal, err := order.CalculatePrices()
if err != nil {
data := CreateSessionData(c, gin.H{
"error": err,
"success": "",
})
priceTotal := priceProducts + shipping.Price
c.HTML(http.StatusOK, "cart.html", data)
return
}
data := CreateSessionData(c, gin.H{
"error": "",
@@ -411,19 +409,85 @@ func (rc *cartItemController) CheckoutHandler(c *gin.Context) {
})
fmt.Println(order)
c.HTML(http.StatusOK, "order.html", data)
c.HTML(http.StatusOK, "orderpreview.html", data)
}
func (rc *cartItemController) OrderView(c *gin.Context) {
shippingMethod := c.Query("shippingMethod")
orderToken := c.Param("token")
c.HTML(http.StatusOK, "checkout.html", gin.H{
"askAddress": (shippingMethod != "pickup"),
"shippingMethod": shippingMethod,
})
order, err := repositories.Orders.GetByToken(orderToken)
if err != nil {
c.HTML(http.StatusBadRequest, "error.html", gin.H{"error": "Order does not exist."})
return
}
shipping, err := models.GetShippingMethod(order.Shipping)
if err != nil {
c.HTML(http.StatusBadRequest, "error.html", gin.H{"error": "Could not get shipping method"})
return
}
priceProducts, priceTotal, err := order.CalculatePrices()
if err != nil {
c.HTML(http.StatusBadRequest, "error.html", gin.H{"error": "Could not calculate final prices"})
return
}
fmt.Printf("Order: %v\n", order)
fmt.Printf("PriceTotal: %v\n", priceTotal)
fmt.Printf("Amount Items: %v\n", len(order.CartItems))
for _, item := range order.CartItems {
fmt.Printf("Cartitem: %v", item)
}
c.HTML(http.StatusOK, "order.html", CreateSessionData(c, gin.H{
"error": "",
"success": "",
"order": order,
"shipping": shipping,
"priceProducts": fmt.Sprintf("%.2f", priceProducts), //round 2 decimals
"priceTotal": fmt.Sprintf("%.2f", priceTotal), //round 2 decimals
}))
}
func (rc *cartItemController) OrderHandler(c *gin.Context) {
//get order by session id
//generate token, preview payment info
confirmation := c.PostForm("confirm-order")
if confirmation == "" {
c.HTML(http.StatusBadRequest, "error.html", gin.H{"error": "Something went wrong, try again later"})
return
}
if confirmation != "true" {
c.HTML(http.StatusBadRequest, "error.html", gin.H{"error": "Order was not confirmed."})
return
}
sessionId := GetSessionId(c)
order, err := repositories.Orders.GetBySession(sessionId)
if err != nil {
c.HTML(http.StatusBadRequest, "error.html", gin.H{"error": "Something went wrong, try again later"})
return
}
order.Status = models.AwaitingPayment
err = order.Validate()
if err != nil {
c.HTML(http.StatusBadRequest, "error.html", gin.H{"error": err})
return
}
_, err = repositories.Orders.Update(order)
if err != nil {
c.HTML(http.StatusBadRequest, "error.html", gin.H{"error": err})
return
}
//TODO: cartItemRepository delete all by session - otherwise items stay in cart after completing order..
c.Redirect(http.StatusFound, fmt.Sprintf("/order/%s", order.Token))
}